问题
Code snippet from 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;
}
Based on document,
template<typename Target, typename Source>
Target lexical_cast(const Source& arg);
1> Returns the result of streaming arg into a standard library string-based stream and then out as a Target object.
2> Source is OutputStreamable
3> Target is InputStreamable
Question1> For User Defined Type (UDT), should the OutputStreamable or InputStreamable always have to deal with std::string
? For example, given a class containing a simple integer as member variable, when we define the operator<<
and operator>>
, what is the implementation code looks like? Do I have to convert the integer as a string? Based on my understanding, it seems that UDT always has to deal with std::string
in order to work with boost::lexical_cast
and boost::lexcial_cast
needs the intermediate std::string
to do the real conversion jobs.
Question2> Why the return value of operator<<
or operator>>
in above code is not reference to std::ostream&
or std::istream&
respectively?
回答1:
To make your class usable with lexical_cast
, just define the "stream" operators for it.
From Boost.LexicalCast Synopsis:
- Source is OutputStreamable, meaning that an
operator<<
is defined that takes astd::ostream
orstd::wostream
object on the left hand side and an instance of the argument type on the right.- Target is InputStreamable, meaning that an
operator>>
is defined that takes astd::istream
orstd::wistream
object on the left hand side and an instance of the result type on the right.- Target is CopyConstructible [20.1.3].
- Target is DefaultConstructible, meaning that it is possible to default-initialize an object of that type [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();
}
The same of course for operator>>
.
来源:https://stackoverflow.com/questions/8630451/enabling-classes-for-use-with-boostlexical-cast