I am trying to pretty print an STL container. What I am trying to is to print elemets of a container separated with a delimiter. However I have came across a couple of problems.
1. g++ vs VC++
ostream& operator<<(ostream& o, const vector<string>& v) {
copy(v.begin(), v.end(), std::ostream_iterator<string>(o,","));
}
int main()
{
vector<string> s_v;
s_v.push_back("one");
s_v.push_back("two");
cout << s_v;
}
g++ (gcc version 4.4.0 on mingw32) can compile it an works fine. VC++ (Visual Studio 9) can not compile this code.
error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'const std::string' (or there is no acceptable conversion)
1> c:\program files (x86)\microsoft visual studio 9.0\vc\include\ostream(653): could be 'std::basic_ostream<_Elem,_Traits> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<_Elem,_Traits> &,const char *)'
1> with
1> [
why is this? Is this code illegal? or it is just VC++ beign VC++?
2. Unused template variable breaks compilation.
if now I add a template to the ostream like this (it is not used, just sitting there)
template <typename T> // <----- Here
ostream& operator<<(ostream& o, const vector<string>& v) {
copy(v.begin(), v.end(), std::ostream_iterator<string>(o,","));
}
int main()
{
vector<string> s_v;
s_v.push_back("one");
s_v.push_back("two");
cout << s_v;
}
gcc can not match the operator anymore.
error: no match for 'operator<<' in 'std::cout << s_v'
and a lot more candidates...
Why? the template is unused. Should it matter?
EDIT: This is solved. I had to return o;
3. Used template
template <typename T>
ostream& operator<<(ostream& o, const vector<T>& v) {
copy(v.begin(), v.end(), std::ostream_iterator<T>(o,","));
return o; // Edited
}
int main()
{
vector<string> s_v;
s_v.push_back("one");
s_v.push_back("two");
vector<int> i_v;
i_v.push_back(1);
i_v.push_back(2);
cout << s_v;
cout << i_v;
}
If I know use the template type. g++ can compile it but then terminates with an exception.
terminate called after throwing an instance of 'std::bad_cast'
what(): std::bad_cast
VC++ is just sitting and watching gcc do all of this. Doesn't compile any of them.
Can someone please clarify this things for me? Thank you.
template<typename T> void Foo() { ... }
, you need to useFoo<Type>()
. Obviously, you can't do that when you overload an operator. When you do useT
, the compiler is able to infer its type, and this is why it works.return o;
to youroperator<<
though. This would most likely crash your program if you didcout << s_v << i_v
.std::
unless it involves a type you've defined somewhere. Otherwise, the code is illegal.std::
, missing return), it works with my system (VC++ 11).