Я бы не сказал, что он предпочитает столько, сколько требуется.
я есть классC
у которого есть оператор приведения к чему угодно. В примере я попытался привести его кstd::string
тремя разными способами:static_cast
конструкторstd::string
и присваиваяstd::string
, Однако компилируется только последний, в то время как другие вызывают ошибку неоднозначного конструктора.
Причина ошибки достаточно ясна: существует много способов конвертацииC
к чему-то, что конструкторstd::string
могу принять. Но в чем разница между этими случаями? Почему оператор приведения работает здесь, как задумано, а не там?
struct C {
template<typename T>
operator T() const {
return T{};
}
};
int main() {
C c;
cout << static_cast<string>(c) << endl; // compile error
string bad(c); // compile error
string ok = c; // compiles successfully
}
UPD: как упомянул в комментариях Болов, эта проблема не воспроизводится с C ++ 17. Я протестировал его с g ++ - 5 и clang-3.8 с -std = c ++ 11 и -std = c ++ 14, и он показывает описанные ошибки.