У меня есть что-то вроде:
#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, то все будет работать так, как ожидалось. Точнее, выбор перегрузки, по-видимому, имеет смысл, когда оба оператора имеют одинаковую квалификацию const.
13.3.3.1.2 точка стандарта заставляет меня думать, что я должен получить преобразование идентичности, конвертируя в bool, используя экземпляр оператора преобразования шаблона с помощью T
= bool
, хотя, очевидно, скрывается скрытность где-то. Может ли кто-нибудь просветить меня о том, какое правило здесь играет здесь?