【发布时间】:2012-09-11 14:49:07
【问题描述】:
后标准草案 n3376 以使用显式转换函数到用户定义类型的示例 (12.3.2:2) 为例:
class Y { };
struct Z {
explicit operator Y() const;
};
void h(Z z) {
Y y1(z); // OK: direct-initialization
}
根据 12.3.2:2,显式转换函数“仅被视为用户定义的直接初始化转换”;但是,这似乎允许:
struct Y { Y(int); };
struct Z {
explicit operator int() const;
};
void h(Z z) {
Y y1(z); // direct-initialization
}
这似乎与标准的意图相冲突,并且确实被 gcc-4.7.1 拒绝:
source.cpp: In function 'void h(Z)':
source.cpp:4:9: error: no matching function for call to 'Y::Y(Z&)'
source.cpp:4:9: note: candidates are:
source.cpp:1:12: note: Y::Y(int)
source.cpp:1:12: note: no known conversion for argument 1 from 'Z' to 'int'
source.cpp:1:8: note: constexpr Y::Y(const Y&)
source.cpp:1:8: note: no known conversion for argument 1 from 'Z' to 'const Y&'
source.cpp:1:8: note: constexpr Y::Y(Y&&)
source.cpp:1:8: note: no known conversion for argument 1 from 'Z' to 'Y&&'
gcc 通过int 拒绝从Z 到Y 的转换是否正确,或者标准确实允许这种用法?
我考虑了上述直接初始化的上下文;根据 8.5:16 中对类类型的直接初始化定义,使用初始化表达式作为其参数调用构造函数,因此通过隐式转换序列 (13.3.3.1) 将其转换为参数类型。由于隐式转换序列是隐式转换 (4:3),因此模型复制初始化 (8.5:14) 而不是直接初始化,因此 12.3.2:2 中的语言必须将表达式作为一个整体来引用。
另请注意,这并不违反 12.3:4(多个用户定义的转换);相同的编译器对删除 explicit 的相同代码感到满意(Clang 和 Comeau 也是如此):
struct Y { Y(int); };
struct Z { operator int(); };
void h(Z z) {
Y y1(z); // direct-initialization
}
我认为 Jesse Good 已经确定了 13.3.1.4:1 中 operator Y 和 operator int 案例之间的区别,但我仍然担心第三种情况:
struct X {};
struct Y { Y(const X &); };
struct Z {
explicit operator X() const;
};
void h(Z z) {
Y y1(z); // direct-initialization via class-type X
}
临时X 的初始化将绑定到Y 的构造函数的单个const X & 参数,按照13.3.1.4:1 在直接初始化上下文中进行,T 为X和S 为Z。我认为这个条款是错误的,应该是:
13.3.1.4 通过用户定义的转换复制初始化类[over.match.copy]
1 - [...] 初始化临时绑定到第一个参数时 一个构造函数,该构造函数将引用可能 cv 限定的
T作为其第一个参数,在“cv2 @”类型的对象的直接初始化 上下文中使用单个参数调用987654340@",还考虑了显式转换函数。 [...]
为了避免混淆,我认为12.3.2:2也应该修改一下:
12.3.2 转换函数[class.conv.fct]
2 - 转换函数可能是显式的 (7.1.2),在这种情况下,它仅被视为直接初始化 (8.5) 的用户定义转换在某些情况下 (13.3.1.4, 13.3. 1.5、13.3.1.6)。 [...]
上面有cmet吗?
【问题讨论】:
-
如果您认为措辞可以改进,我实际上会推荐 C++ 讨论组之一。
-
@LucDanton 我想说我没有时间参加讨论组,但显然不是这样。
标签: c++ c++11 initialization type-conversion language-lawyer