In the sample code below, it shows that boost::tuple can be created implicitly from the first template argument.
Because of that I am not able to write a <<
operator as it becomes ambiguous.
Also I don't understand why ostringstream& << float
is also ambiguous. This does not have any implicit construction. Why does this also give ambiguous error?
#include <iostream>
#include <boost/tuple/tuple.hpp>
#include <sstream>
#include <string>
using namespace std;
class Myclass
{
};
typedef boost::tuple<int,float,Myclass> Mytuple;
ostringstream& operator<<(ostringstream& os_, Mytuple tuple_)
{
float f = tuple_.get<1>();
//os_ << (int)tuple_.get<0>(); // Error because int is implicitly converted into Mytuple. WHYY?
//os_ << tuple_.get<1>(); // No Clue Why this is ambiguous.
//os_ << tuple_.get<2>(); // Error because no matching operator. Fine.
return os_;
}
int main()
{
Mytuple t1;
t1 = 3; // Working because int is implicitly converted into Mytuple!! WHY?
//t1 = 3.0f; // Error because no matching constructor. Fine.
return 0;
}
Error Mesasge:
tupleTest2.C:18: error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
The problem is not with the tuple, but with your operator. This works fine :
ostream& operator<<(ostream& os_, Mytuple tuple_)
{
os_ << tuple_.get<0>(); // Error because int is implicitly converted into Mytuple. WHYY?
os_ << tuple_.get<1>(); // No Clue Why this is ambiguous.
//os_ << tuple_.get<2>(); // Error because no matching operator. Fine.
return os_;
}
The problem is that the ostringstream inherit operator<<
from ostream, which has this signature : ostringstream& operator<<(ostringstream& os_, Mytuple tuple_)
is allowed. Then the
ostream& operator<<(ostream& os, T t)
(change T with all available types in c++, see operator<< reference page
EDIT
Here is a simplified example (without a tuple) :
ostringstream& operator<<(ostringstream& os_, Mytuple tuple_)
{
const int i = tuple_.get<0>();
os_ << i; // error in this line
return os_;
}
and the error is now :
dfg.cpp: In function ‘std::ostringstream& operator<<(std::ostringstream&, Mytuple)’:
dfg.cpp:18: error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
/usr/lib/gcc/i386-redhat-linux/4.3.0/../../../../include/c++/4.3.0/bits/ostream.tcc:111: note: candidate 1: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char, _Traits = std::char_traits<char>]
dfg.cpp:14: note: candidate 2: std::ostringstream& operator<<(std::ostringstream&, Mytuple)
The above error message says : it is not possible to choose between two operators operator<<(ostream&,...)
and operator<<(ostringstream&,...). This also raises another question : why on earth do you need
operator<<(ostringstream&,...)`?