Рассмотрим следующий простой пример
struct C
{
template <typename T> operator T () {return 0.5;}
operator int () {return 1;}
operator bool () {return false;}
};
int main ()
{
C c;
double x = c;
std::cout << x << std::endl;
}
При компиляции с помощью Clang он дает следующую ошибку:
test.cpp:11:12: error: conversion from 'C' to 'double' is ambiguous
double x = c;
^ ~
test.cpp:4:5: note: candidate function
operator int () {return 1;}
^
test.cpp:5:5: note: candidate function
operator bool () {return false;}
^
test.cpp:3:27: note: candidate function [with T = double]
template <typename T> operator T () {return 0.5;}
^
1 error generated.
Другие компиляторы генерируют подобные ошибки, например, GCC и Intel iclc
Если я удалю operator int
и operator bool
. Он отлично компилируется и работает, как ожидалось. Если удалить только один из них, то есть сохранить оператор шаблона и сказать operator int
, тогда всегда выбирается версия без шаблона.
Я понимаю, что только когда перегруженные шаблоном и не шаблоном функции равны в том смысле, что они оба идеально подходят или оба требуют одной и той же последовательности конверсии, предпочтительной будет версия без шаблонов. Однако в этом случае кажется, что компилятор не видит шаблон оператора как идеальное совпадение. И когда присутствуют перегрузки bool
и int
, то, естественно, они считают, что они неоднозначны.
В заключение, мой вопрос заключается в том, почему шаблон оператора не считается идеальным совпадением в этом случае?