Как прочитать значение с оператором >>, но нет конструктора по умолчанию для значения? - PullRequest
2 голосов
/ 29 октября 2009
template <class T>
T Read () {
  T t;
  cin >> t;
  if (cin.fail()) {
    // ...
  }
  return t;
}

Этот универсальный код считывает значение типа T с некоторой дополнительной обработкой ошибок. Он полагается на наличие оператора >>, который может анализировать T, и, таким образом, его можно расширять для новых типов.

Чего я не понял, так это того, что в T есть конструктор по умолчанию. Теперь я столкнулся с этой проблемой.

Какие у меня варианты?

Как правильно это сделать?

1 Ответ

5 голосов
/ 29 октября 2009

Потоковая передача из входного потока всегда предполагает полностью построенный объект для записи. Вы не можете обойтись без необходимости создания объекта, все, что вы можете сделать, - это сделать это разными способами.

Одним из способов сделать это могут быть черты. Стандартные черты будут делать то, что вы делаете:

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; 
}

Если у вас есть тип X, который не может быть сконструирован по умолчанию, но может быть сконструирован из istream, следующая специализация сделает:

template<>
struct istream_traits<X>
{
  inline static X read(std::istream& is)
  {
    return X(is);
  }
}
...