|
From: Sam Stump on 21 Aug 2006 20:33 The code below does not compile with VC8. The error is: sample.cpp(36) : error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'const std::vector<_Ty>' (or there is no acceptable conversion) with [ _Ty=int ] but it is clearly there. Is this conformant behavior or a bug? ================= begin code ===================== // sample.cpp #include <vector> #include <iostream> // move the operator below inside the namespace, then it will compile ... template <class T> std::ostream& operator<<(std::ostream& ostr, const std::vector<T>& v) { // output comma delimited vector elements ... std::vector<T>::const_iterator end = v.end(); for (std::vector<T>::const_iterator it = v.begin(); it != end; ++it) { ostr << *it; if (it + 1 != end) ostr << ", "; } return ostr; } namespace formatter { template <class T> class bracketed { public: bracketed(const T& t) : value(t) {} const T& value; private: // not implemented ... bracketed<T>& operator=(const bracketed<T>&); }; template <class T> std::ostream& operator<<(std::ostream& ostr, const bracketed<T>& v) { // enclose value in brackets ... return ostr << '[' << v.value << ']'; } }; int main() { using formatter::bracketed; // easy example ... int x = 21014; std::cout << bracketed<int>(x) << std::endl; // more complicated example ... std::vector<int> v; v.push_back(2); v.push_back(1); v.push_back(0); v.push_back(1); v.push_back(4); std::cout << bracketed<std::vector<int> >(v) << std::endl; } [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: dasjotre on 22 Aug 2006 10:27 compiler first looks at the enclosing namespace and then into std namespace because vector template is from there (ADL) and it finds many '<<' operators that don't fit the purpose. because of the ADL rules it doesn't look any further. > // move the operator below inside the namespace, then it will compile ... and that would be the solution for it (the most complete solution would be putting it inside std namespace) <snip> [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: dasjotre on 22 Aug 2006 10:28 >> and that would be the solution for it (the most complete solution would be >> putting it inside std namespace) don't! [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Earl Purple on 22 Aug 2006 10:28 Sam Stump wrote: > The code below does not compile with VC8. The error is: > > sample.cpp(36) : error C2679: binary '<<' : no operator found which takes > a right-hand operand of type 'const std::vector<_Ty>' (or there is no > acceptable conversion) > with > [ > _Ty=int > ] > > but it is clearly there. Is this conformant behavior or a bug? > ================= begin code ===================== > // sample.cpp > > #include <vector> > #include <iostream> > > // move the operator below inside the namespace, then it will compile ... > template <class T> > std::ostream& operator<<(std::ostream& ostr, const std::vector<T>& v) > { > // output comma delimited vector elements ... > std::vector<T>::const_iterator end = v.end(); > for (std::vector<T>::const_iterator it = v.begin(); it != end; ++it) { > ostr << *it; > if (it + 1 != end) ostr << ", "; > } > return ostr; > } //etc As far as I am aware this is conformant, you can only overload operators if one of the types is your own, and neither of them are, because vector belongs in namespace std. You should therefore write a wrapper. For output this is easy enough. template < typename SEQ > class const_sequence_wrapper { public: // put some typedefs here const SEQ & seq; /*explicit*/ const_sequence_wrapper( const SEQ & seq_in ) : seq( seq_in ) { } // define begin() and end() }; then implement operator<< in terms of that. In fact now we've created a wrapper for the purpose of printing, we can specialise it with extra parameters regarding how we will output it, eg what delimiter we use, any "beginning of sequence" and "end of sequence" markers (the latter is particularly useful). You may wish, for example, to use tab as delimiter and new-line as end-of-sequence. [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Jack Klein on 22 Aug 2006 10:21
On 21 Aug 2006 20:33:28 -0400, Sam Stump <sMaUmDuDeYlS.HsOtEuSmp(a)verizon.net> wrote in comp.lang.c++.moderated: > The code below does not compile with VC8. The error is: > > sample.cpp(36) : error C2679: binary '<<' : no operator found which takes > a right-hand operand of type 'const std::vector<_Ty>' (or there is no > acceptable conversion) > with > [ > _Ty=int > ] > > but it is clearly there. Is this conformant behavior or a bug? [snip] Almost certainly not the problem you are questioning, but your program is ill-formed and has undefined behavior. Your code is not allowed to define identifiers with a leading underscore followed by an upper case latter, or containing two consecutive underscores anywhere within them. All identifiers fitting these patterns are reserved for the implementation in all contexts. -- Jack Klein Home: http://JK-Technology.Com FAQs for comp.lang.c http://c-faq.com/ comp.lang.c++ http://www.parashift.com/c++-faq-lite/ alt.comp.lang.learn.c-c++ http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |