【发布时间】:2015-05-06 21:48:47
【问题描述】:
我有一些类似的东西:
#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 点让我认为我应该进行身份转换,转换为布尔值,使用带有T = bool 的模板转换运算符实例化,尽管显然有一个微妙的隐藏某处。有人能告诉我这里有什么规则吗?
【问题讨论】:
-
运算符 Foo* 的优先级高于模板运算符,并且 Foo* 可以隐式转换为 bool,因此编译器选择 Foo* 重载而不是模板。
-
创建身份转换的潜在实例化不应该具有更高的优先级吗?似乎常量性主要是选择正确转换的原因
-
如果是模板化,显然不会
-
@Creris 不正确。
标签: c++ templates overload-resolution