【发布时间】:2012-07-18 08:22:33
【问题描述】:
该标准似乎提供了两条规则来区分涉及用户定义的转换运算符的隐式转换序列:
13.3.3 最佳可行函数[over.match.best]
[...] 一个可行函数 F1 被定义为比另一个可行函数更好的函数 F2 如果 [...]
- 上下文是由用户定义的转换初始化(见 8.5、13.3.1.5 和 13.3.1.6)和 从 F1 的返回类型到目标类型的标准转换序列(即, 实体被初始化)是比标准转换序列更好的转换序列 F2 的返回类型到目标类型。
13.3.3.2 对隐式转换序列进行排名[over.ics.rank]
3 - 两个相同形式的隐式转换序列是无法区分的转换序列,除非其中之一 以下规则适用:[...]
- 如果用户定义的转换序列 U1 包含相同的用户定义的转换函数或构造函数或聚合,则它们是比另一个用户定义的转换序列 U2 更好的转换序列 U1的初始化和第二个标准转换顺序优于第二个标准 U2的转换序列。
据我了解,13.3.3允许编译器区分不同的用户定义的转换运算符,而13.3.3.2允许编译器区分不同的函数 (某些函数 f 的重载),每个函数都需要在其参数中进行用户定义的转换(请参阅我对 Given the following code (in GCC 4.3) , why is the conversion to reference called twice? 的侧边栏)。
还有其他规则可以区分用户定义的转换序列吗? https://stackoverflow.com/a/1384044/567292 的答案表明 13.3.3.2:3 可以根据隐式对象参数(转换运算符)或构造函数的单个非默认参数的 cv 限定来区分用户定义的转换序列或聚合初始化,但我不明白这有什么关系,因为这需要在相应用户定义的转换序列的第一个标准转换序列之间进行比较,标准似乎没有提及。
假设 S1 优于 S2,其中 S1 是 U1 的第一个标准转换序列,S2 是 U2 的第一个标准转换序列,是不是 U1 优于 U2?换句话说,这段代码格式正确吗?
struct A {
operator int();
operator char() const;
} a;
void foo(double);
int main() {
foo(a);
}
g++ (4.5.1)、Clang (3.0) 和 Comeau (4.3.10.1) 接受它,更喜欢非 const 限定的 A::operator int(),但我希望它会被拒绝模棱两可,因此格式不正确。这是标准的缺陷还是我对它的理解?
【问题讨论】:
-
嗯,
char -> double和int -> double都是可行的,排名相同的默认转化。但是A -> int比const A -> char更受欢迎,因为它不需要额外的转换A -> const A。 -
@KerrekSB 我接受 S1 优于 S2,其中 S1 是 U1 的第一个标准转换序列,S2 是 U2 的第一个标准转换序列。但是为什么会说 U1 比 U2 好呢?
标签: c++11 c++ constructor implicit-conversion language-lawyer conversion-operator