考虑以下示例:
struct ConvertibleStruct {};
enum class ConvertibleEC {};
struct Target {
// Implicit conversion constructors
Target(ConvertibleStruct) {}
Target(ConvertibleEC) {}
};
Target operator~(const Target& t) {
return t;
}
Target anotherFunction(const Target& t) {
return t;
}
int main() {
ConvertibleStruct t;
ConvertibleEC ec;
~t; // 1. Works finding the operator overloaded above
~ec; // 2. Fails to compile on clang 3.4 and gcc 4.8.2
operator~(ec); // 3. Works finding the operator overloaded above
anotherFunction(ec); // 4. Works
}
编译器版本:
以上调查结果适用于clang 3.4
和gcc 4.8.2
。测试2.实际上使用gcc 4.7.3
在-std=c++11
上编译正常。可能是早期GCC C ++ 11实现中的一个错误?
断言:
~
运算符时会检查用户定义的隐式转换。 enum class
个对象。问题:
答案 0 :(得分:4)
第二个测试~ec
遇到了表达式中运算符名称查找的特性:[over.match.oper] / 3(来自"古代" N3797):
对于一元运算符
@
,其操作数的类型为cv-nonqualified versionT1
[...]非会员候选人的集合是不合格的结果 根据表达式在表达式的上下文中查找
operator@
通常的非限定函数调用中的名称查找规则 除了忽略所有成员函数。 但是,如果没有操作数 具有类类型,只有查找集中的非成员函数 具有类型T1
的第一个参数或“可能的参考” cv-qualified)T1
“,当T1
是枚举类型 [...] 时 候选职能。
因此,::operator~(const Target&)
不应与for表达式一起使用,并且将一元运算符应用于ConvertibleEC
类型的操作数。
对于第一个~t
,操作数属于类类型,上述异常不适用。
第三次和第四次测试都不使用运算符查找,而是通常不合格的查找。通常不合格的查找会找到::operator~(const Target&)
(在案例1和3中)和anotherFunction
(在案例4中)。