I have stumbled upon an error for which I cannot grasp the reason.
I think it basically gets down to this error:
error: no matching function for call to ‘std::basic_ostream<char>::operator<<(const std::basic_string<char>&)’
I looked into specification on http://www.cplusplus.com and indeed it says there is no definition for std::ostream::operator<< with std::string as an argument.
My question is, what happens when one writes std_ostream_instance << std_fancy_string;. I believe it is one of the most common invocations ( e.g. std::out << std::string("Hello world!") ) next to const char*.
The error originates from these lines:
template<typename T>
void Log::_log(const T& msg)
{ _sink->operator<<( msg ); }
_sink is defied as std::ostream*
There are some wrapping functions around but it breaks here.
I think I could work around by writing
template<>
void Log::_log<std::string>(const std::string& msg) {
_sink->operator<<( msg.c_str() );
}
since there is ostream& operator<< (ostream& out, const unsigned char* s ); defined by default.
I just see no reason why it is not guessed automatically since it clearly works in simple use like cout << any_std_string.
Not sure if this is relevant but I want to be able to pass down through my log functions anything than can be handled by std::ostream. I used explicit non-templated declarations but decided to move to template for log(const T& anything_to_log) to refacator it. It seemed plain stupid to have 5+ overloads. I get the error when I try compiling something like Log::log( std::string("test case") ).
It looks like something stupid-simple but I cannot get it on my own. Tried to google and search stack to no avail.
With regards, luk32.
PS. I checked the work-around and it works. Why it’s not implicitly done ?
operator <<overloads are not members ofostream. They are freestanding functions, for exampleTry