我沿着线的东西:模板转换操作符的优先级和常量性
#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
如果我删除了常量,或使测试实例常量,则一切正常。 更准确地说,当两个操作符具有相同的常量限定时,重载选择似乎是有意义的。
13.3.3.1.2点的标准让我觉得我应该得到一个身份转换,转换成一个布尔值,使用模板变换操作实例化一个T
= bool
,但显然是有一个精妙藏在什么地方。有人能告诉我这里有什么规则?
运算符Foo *具有比模板运算符更高的优先级,并且Foo *可以隐式转换为bool,所以编译器会选择Foo *重载而不是模板。 – Creris
创建身份转换的潜在实例是否应该具有更高的优先级? 似乎常量大多是什么使得选择正确的转换 – chouquette
显然不是如果它是模板 – Creris