У меня есть кое-что вдоль линий:шаблона приоритета оператора преобразования и константность
#include <iostream>
class Foo;
struct Test
{
template <typename T>
operator T() const // <----- This const is what puzzles me
{
std::cout << "Template conversion" << std::endl;
return T{};
}
operator Foo*()
{
std::cout << "Pointer conversion" << std::endl;
return nullptr;
}
};
int main()
{
Test t;
if (t)
{
std::cout << "ahoy" << std::endl;
}
bool b = (bool)t;
Foo* f = (Foo*)t;
}
Он строит хорошо, но когда я запускаю его, в то время как я ожидаю получить
$> ./a.out
Template conversion
Template conversion
Pointer conversion
я вместо того, чтобы получить
$> ./a.out
Pointer conversion
Pointer conversion
Pointer conversion
Если я удаляю const или создаю экземпляр Test const, то все работает так, как ожидалось. Точнее, выбор перегрузки, по-видимому, имеет смысл, когда оба оператора имеют одинаковую квалификацию.
13.3.3.1.2 точка стандарта заставляет меня думать, что я должен получить преобразование идентичности, преобразование в BOOL, используя преобразование шаблона оператора экземпляра с T
= bool
, хотя, очевидно, скрывается где-то тонкость. Может ли кто-нибудь просветить меня о том, какое правило здесь играет?
оператор Foo * имеет более высокий приоритет, чем оператор шаблона, а Foo * неявно конвертируется в bool, поэтому компилятор выбирает перегрузку Foo *, а не шаблонную. – Creris
Должен ли потенциальный экземпляр, создающий преобразование идентичности, иметь более высокий приоритет? Кажется, что константа - это в основном то, что делает правильное преобразование выбранным – chouquette
, по-видимому, нет, если оно задумано. – Creris