Pergunta

template <class T>
T Read () {
  T t;
  cin >> t;
  if (cin.fail()) {
    // ...
  }
  return t;
}

Este código genérico valor do tipo T ler com alguma manipulação de erro adicional. Ele se baseia em ter operator >> que pode analisar T, e, desta forma, é extensível a novos tipos.

O que eu não sabia é que ele depende de T ter um construtor padrão. Agora eu bati para esse problema.

Quais são as minhas opções?

O que é o caminho certo para fazê-lo?

Foi útil?

Solução

streaming a partir de um fluxo de entrada assume sempre um objeto totalmente construído para escrever em. Você não pode ficar em torno de ter que construir um objeto, tudo que você pode fazer é permitir diferentes maneiras de fazer isso.

Uma maneira de fazer isso poderia ser traços. Os traços padrão faria o que você está fazendo:

template< typename T >
struct istream_traits
{
  inline static T read(std::istream& is)
  {
    T obj;
    is >> obj;
  }
}

template< typename T >
inline T read(std::istream& is)
{
  is >> std::ws;
  T obj = istream_traits<T>::read(is);
  is >> std::ws;
  if(!is.eof()) throw "dammit!";
  return obj; 
}

Se você tem um X tipo que não pode ser construído-padrão, mas pode ser construído a partir de um istream, a seguinte especialização faria:

template<>
struct istream_traits<X>
{
  inline static X read(std::istream& is)
  {
    return X(is);
  }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top