6

When I write code like this:

struct foo {
    operator int() const { return 1; }
};
int main() {
    foo a, b;
    auto tmp = (a < b);
}

it works, but while I write code like this:

struct foo {
    operator string() const { return string("foo"); }
};
int main() {
    foo a, b;
    auto tmp = (a < b);
}

Compiler(clang++) says that error: invalid operands to binary expression ('foo' and 'foo')

I wonder why, as both string type and int type have comparison operators, but when foo has a user defined int conversion, it will implicit convert to int to compare, however when foo only has a user defined string conversion, compiler doesn't do implicit conversion though (string)a<(string)b works well.

1 Answers1

1

I think the problem is that string is not a basic type. std::string is a specialization of a template, specifically std::basic_string<char>

So operator < is defined as

template <class CharT, class Traits, class Allocator>
    bool operator< (const std::basic_string<CharT, Traits, Allocator> &_Left,  const std::basic_string<CharT, Traits, Allocator> &_Right);

It will work with:

auto tmp = (static_cast<std::string>(a) < static_cast<std::string>(b));

Then operator < becomes:

bool std::operator< <char, std::char_traits<char>, std::allocator<char>>(const std::string &_Left, const std::string &_Right)
JHBonarius
  • 10,824
  • 3
  • 22
  • 41
  • 2
    And because user defined conversion are not considered for template function specialization. See this related answer: [http://stackoverflow.com/questions/42252023/implicit-conversion-operator-priority/42253006#42253006]. – Oliv Feb 20 '17 at 17:14