Reputation: 952
As in the question, if I define a string operator in my class:
class Literal {
operator string const () {
return toStr ();
};
string toStr () const;
};
and then I use it:
Literal l1 ("fa-2bd2bc3e0");
cout << (string)l1 << " Declared" << endl;
with an explicit cast everything goes right, but if I remove the (string) the compiler says that it needs a cast operator declared in std::string. Shouldn't it cast my type automatically? SOLVED: I'm overloading operator<< (ostream& os, const Literal& l).
Upvotes: 3
Views: 2473
Reputation: 72356
Short answer: Keep using a cast or toStr()
, or write your own operator<<
function. (I would prefer l1.toStr()
to (string)l1
.)
Long answer: This might work if the Standard Library had a function
std::ostream& operator<<( std::ostream&, std::string const& );
Which it almost does, but not technically. Both ostream
and string
are really typedefs of template instantiations. And there's a template function for inserting one into the other.
// This is somewhat simplified. For the real definitions, see the Standard
// and/or your complying implementation's headers.
namespace std {
typedef basic_string<char> string;
typedef basic_ostream<char> ostream;
template <typename CharT>
basic_ostream<CharT>& operator<<(
basic_ostream<CharT>&,
basic_string<CharT> const&);
}
So when you use cout << str
where the type of str
is std::string
, it can figure out to use that template function, with CharT = char
.
But C++ doesn't allow you to have the compiler figure out both an implicit type conversion (Literal
to string
) and deduce template function template parameters (CharT = char
) on the same call.
Upvotes: 5
Reputation: 28217
No.. std::string would have to have a constructor that took Literal as an argument.
What you could do is overload operator << for your Literal class and have it cast and insert into the stream in there.
ostream &operator <<(std::ostream &stream, const Literal &rhs)
{
stream << (string) rhs;
return stream;
}
Upvotes: 10