The strange behavior of the `operator string()` type conversion function

I have a C class and I want to convert it to string by using the operator string() syntax, but as I wrote in the comment, something strange happens.

class C {
public:
    operator string()
    {
        return string("anything");
    }
};
int main()
{
    C c;
    cout << string("test:").append(c) << endl; //success
    //cout << string("test:")+c<< endl;//fail
    //cout << c.append("test:") << endl;//fail
    cout << string("test:") + static_cast<string>(c) << endl;//success
}

Solution 1:

//cout << string("test:")+c<< endl;//fail

std::operator+(std::basic_string) are templates. Implicit conversion won't be considered in template argument deduction, which causes the deduction failing on the 2nd operand c.

Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.

And

//cout << c.append("test:") << endl;//fail

C doesn't have member function named append, then the code fails. You can convert c to std::string explicitly then call append on it like static_cast<string>(c).append("test:").

cout << string("test:").append(c) << endl; //success

string("test:").append expects an std::string, then c is converted to std::string implicitly and passed to append. (Note that append are non-template member functions.)

cout << string("test:") + static_cast<string>(c) << endl;//success

c is converted to std::string explicitly, then two std::strings are passed to std::operator+(std::basic_string).