Включение классов для использования с boost :: lexical_cast - PullRequest
8 голосов
/ 25 декабря 2011

Фрагмент кода из lexical_cast :

class lexical_castable {
public:
  lexical_castable() {};
  lexical_castable(const std::string s) : s_(s) {};

  friend std::ostream operator<<
    (std::ostream& o, const lexical_castable& le);
  friend std::istream operator>>
    (std::istream& i, lexical_castable& le);

private:
  virtual void print_(std::ostream& o) const {
    o << s_ <<"\n";
  }

  virtual void read_(std::istream& i) const {
    i >> s_;
  }

  std::string s_;
};

std::ostream operator<<(std::ostream& o,
  const lexical_castable& le) {
  le.print_(o);
  return o;
}

std::istream operator>>(std::istream& i, lexical_castable& le) {
  le.read_(i);
  return i;
}

На основе документа ,

template<typename Target, typename Source>
  Target lexical_cast(const Source& arg);

1> Возвращает результатпотоковой передачи аргумента arg в стандартный поток на основе строк библиотеки, а затем в виде целевого объекта.

2> Source is OutputStreamable

3> Target is InputStreamable

Question1 > Для определяемого пользователем типа (UDT), должен ли OutputStreamable или InputStreamable всегда иметь дело с std::string?Например, если в качестве переменной-члена задан класс, содержащий простое целое число, когда мы определяем operator<< и operator>>, как выглядит код реализации?Должен ли я преобразовать целое число в строку?Исходя из моего понимания, кажется, что UDT всегда должен иметь дело с std::string, чтобы работать с boost::lexical_cast, а boost::lexcial_cast нужен промежуточный std::string для выполнения реальных конверсионных заданий.

Question2 > Почему возвращаемое значение operator<< или operator>> в вышеприведенном коде не соответствует std::ostream& или std::istream& соответственно?

1 Ответ

7 голосов
/ 25 декабря 2011

Чтобы ваш класс можно было использовать с lexical_cast, просто определите для него «потоковые» операторы. От Boost.LexicalCast Сводка :

  • Source - OutputStreamable, что означает, что определен operator<<, который принимает std::ostream или std::wostream объект с левой стороны и экземпляр типа аргумента справа.
  • Target is InputStreamable, это означает, что определен operator>>, который принимает объект std::istream или std::wistream с левой стороны и Экземпляр типа результата справа.
  • Цель - CopyConstructible [20.1.3].
  • Target is DefaultConstructible, то есть возможно инициализировать объект этого типа по умолчанию [8.5, 20.1.4].

// either inline friend, out-of-class friend, or just normal free function
// depending on whether it needs to access internel members
// or can cope with the public interface
// (use only one version)
class MyClass{
  int _i;
public:
  // inline version
  friend std::ostream& operator<<(std::ostream& os, MyClass const& ms){
    return os << ms._i;
  }

  // or out-of-class friend (friend declaration inside class only)
  friend std::ostream& operator<<(std::ostream& os, MyClass const& ms);

  // for the free function version
  int get_i() const{ return _i; }
};

// out-of-class continued
std::ostream& operator<<(std::ostream& os, MyClass const& ms){
  return os << ms._i;
}

// free function, non-friend
std::ostream& operator<<(std::ostream& os, MyClass const& ms){
  return os << ms.get_i();
}

То же самое, конечно, для operator>>.

...