Re: [Boost-users] Boost Variant OutputStreamable

The operator << must be defined in the boost namespace.
See the error message of VC:see reference to function template instantiation
'std::basic_ostream<_Elem,_Traits> &boost::operator
<<
I apologise for emailing you directly .. but i canno access the mailing list from work.. However in response to your response.
The following doesn't compile either .. I get the error
error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'const T0' (or there is no acceptable conversion)
On VC8
#include<iostream> #include<vector> #include<string>
#include
std::basic_ostream<char> &operator<<(std::basic_ostream<char> &theostream,const std::vector<unsigned long> &theVector) { for(unsigned long i(0);i
struct TpTemplateVariant { typedef boost::variant< std::vector<unsigned long>,
int,
std::string
BoostVariant; };
typedef TpTemplateVariant::BoostVariant Tpvariant;
int main () {
Tpvariant p(5); std::cout << p;
return 0;
*********************************************************************************** The Royal Bank of Scotland plc. Registered in Scotland No 90312. Registered Office: 36 St Andrew Square, Edinburgh EH2 2YB. Authorized and regulated by the Financial Services Authority
This e-mail message is confidential and for use by the addressee only. If the message is received by anyone other than the addressee, please return the message to the sender by replying to it and then delete the message from your computer. Internet e-mails are not necessarily secure. The Royal Bank of Scotland plc does not accept responsibility for changes made to this message after it was sent.
Whilst all reasonable care has been taken to avoid the transmission of viruses, it is the responsibility of the recipient to ensure that the onward transmission, opening or use of this message and any attachments will not adversely affect its systems or data. No responsibility is accepted by The Royal Bank of Scotland plc in this regard and the recipient should carry out such virus and other checks as it considers appropriate. Visit our websites at: http://www.rbos.com http://www.rbsmarkets.com ***********************************************************************************
Download this as a file

Ovanes Markarian wrote:
namespace boost { template <typename T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) { for(typename std::vector<T>::size_type i = 0; i < v.size(); ++i) os << v[i] << std::endl;
return os; } }
No, this is not correct (even though it works with VC) and has nothing to do with boost::variant. The only correct place for this operator<< is in namespace std. Of course you aren't supposed to put things there, but...

Sorry, you are right. I forgot that all operators are overloaded or defined in std namespace. But still it would be nice as hint in the documentation, that this operator should be from std namespace. With Kind Regards, Ovanes Markarian On Mon, June 26, 2006 13:25, Peter Dimov wrote:
Ovanes Markarian wrote:
namespace boost { template <typename T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) { for(typename std::vector<T>::size_type i = 0; i < v.size(); ++i) os << v[i] << std::endl;
return os; } }
No, this is not correct (even though it works with VC) and has nothing to do with boost::variant.
The only correct place for this operator<< is in namespace std. Of course you aren't supposed to put things there, but...

Ovanes Markarian wrote:
Sorry,
you are right. I forgot that all operators are overloaded or defined in std namespace.
It's a bit more subtle than that. As a general rule, an operator needs to be defined in the namespace of the class for which it applies. If you had std::ostream& operator<<( std::ostream& os, my::X const & x ); you'd need to put this operator in namespace my, because that's where the class my::X resides. All this assumes that your compiler supports argument-dependent lookup (ADL); for older compilers, the rule is "put the operator wherever it appears to work." However, since the operator you are defining: template <typename T> std::ostream& operator<<( std::ostream& os, const std::vector<T>& v ); applies to std::vector, it needs to be defined in namespace std. In principle, a class N::X is supposed to also define the necessary support operators in namespace N, but std::vector doesn't do that (mainly because it isn't clear how is this operator supposed to work; there are many legitimate ways to output a sequence.) This is a general C++ problem, not specific to Boost.Variant, so it's understandable why the documentation doesn't mention it.

Peter, thanks for you answer. I anderstand this all and agree with you. But I still think, that a hint, note etc. in the documentation could be useful. Most of the boost docs are in form of tutorials and are not just dry specifications for some interfaces and their concepts. That's why I think this kind of note, hint whatever could be useful. With Kind Regards, Ovanes Markarian On Mon, June 26, 2006 19:56, Peter Dimov wrote:
Ovanes Markarian wrote:
Sorry,
you are right. I forgot that all operators are overloaded or defined in std namespace.
It's a bit more subtle than that. As a general rule, an operator needs to be defined in the namespace of the class for which it applies. If you had
std::ostream& operator<<( std::ostream& os, my::X const & x );
you'd need to put this operator in namespace my, because that's where the class my::X resides.
All this assumes that your compiler supports argument-dependent lookup (ADL); for older compilers, the rule is "put the operator wherever it appears to work."
However, since the operator you are defining:
template <typename T> std::ostream& operator<<( std::ostream& os, const std::vector<T>& v );
applies to std::vector, it needs to be defined in namespace std.
In principle, a class N::X is supposed to also define the necessary support operators in namespace N, but std::vector doesn't do that (mainly because it isn't clear how is this operator supposed to work; there are many legitimate ways to output a sequence.)
This is a general C++ problem, not specific to Boost.Variant, so it's understandable why the documentation doesn't mention it.
participants (2)
-
Ovanes Markarian
-
Peter Dimov