I'm learning more about implicit conversion operators, and I've noticed something strange with implicit user-defined conversions for strings. Found below is the code.
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
class A {
public:
A() {
*value = "YIKERS";
}
operator string&() {
return *this->value;
}
string* value;
};
int main() {
A abc;
cout << abc << endl;
// compile error: invalid operands to binary expression ('std::__1::ostream' (aka
// 'basic_ostream<char>') and 'A')
return 0;
}
Any ideas as to why I'm getting this compilation error? I'm thinking this could mean that the object isn't being implicitly converted to a string? If so, why not? Is there a way to fix this? The conversion operator works perfectly fine for other data types like int, float, char, etc.
First of all, I think you're not using
std::string value
as intended. This causes another compile error (at least on gcc 10.2). It seems like you want a string and you're using a pointer to a string. This can be fixed by replacestring* value
withstring value
,operator string&()
withoperator string()
and*value = "YIKERS'
withvalue = "YIKERS"
. For the last one you might also want to check initializer lists.Regarding the current compile error:
The compile error is caused by the code
cout << abc
trying to use operator<< on anabc
which is an object of typeA
. However, you did not overload this operator. In your example this could be something likeEven if you have a user-defined conversion to
std::string
you would still get compile time errors. This link explains it better than I think I could Why cannot use cout with user-defined conversion to std::string?This is how I understand the explanation from link above:
string
header defines the following overload foroperator<<
forstd::basic_ostream
:Also,
std::string
is actually a typedef forstd::basic_string<char>
.However, if the conversion is implicit the following rule kicks in:
So, the compiler cannot deduce the second parameter for the function (e.g.
const std::basic_string<CharT, Traits, Allocator>& str
) fromA
. It can, however, deduce it forstring
so you can explicitly convertabc
tostring
likestatic_cast<string>(abc)
and that would work.