' auto x = type{…} '初始化语法和'显式'转换操作符- clang vs gcc
`auto x = type{...}` initialization syntax and `explicit` conversion operator - clang vs gcc
给定此代码(on wandbox):
struct X
{
explicit operator int() { return 0; }
};
int main()
{
auto y = int{X{}};
}
和以下编译器选项:
-std=c++1z -Wall -Wextra -Wpedantic
g++
(测试版本:7、6.1、5.3)拒绝编译代码,出现以下错误错误:初始化时无法将'X'转换为'int'
clang++
(测试版本:4、3.8、3.6)愉快地编译代码片段
哪个编译器在这里做正确的事情?
cppreference似乎表明auto var = type{...}
语法应该触发显式转换。
使用http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/n4606.pdf我认为c++是错误的。
8.6.4第3.7条规定:
—否则,如果初始化列表中只有一个E类型的元素要么T不是引用类型,要么它的引用类型是与E相关的引用,初始化的对象或引用该元素(通过copy-initialization for copy-list-initialization),或者通过直接初始化(直接列表初始化);如果一个需要缩小转换(见下文)来将元素转换为T,程序是病态的。
意味着在非类类型的情况下直接使用init,这导致了8.6第17.7条:
-否则,如果源类型是一个(可能是cv限定的)类考虑类型、转换函数。适用的转换函数被枚举(13.3.1.5),并选择最好的函数通过重载解析(13.3)。用户定义的转换方法将初始化式表达式转换为正在初始化的对象。如果转换不能完成或正在进行歧义,初始化是病态的。
最后13.3.1.5声明直接初始化考虑显式和隐式转换:
-考虑S及其基类的转换函数。那些没有隐藏在S中的非显式转换函数并产生类型T或可通过a转换为类型T的类型标准转换序列(13.3.3.1.1)是候选函数。,直接初始化,那些显式的转换函数不隐藏在S中,生成类型T或可转换的类型到类型T的限定转换(4.5)也是候选的函数。返回cv限定类型的转换函数是被认为为this生成该类型的cv-不限定版本选择候选函数的过程。转换函数返回"对cv2 X的引用"返回左值或xvalue,取决于引用类型为"cv2 X",因此被认为是在选择候选函数的过程中,yield X。
- C++:用户定义的显式类型转换函数错误
- 显式 std::exception_ptr 转换为 bool 不存在.VS2010 错误?
- 将显式实例化的函数模板与转换匹配
- 共享指针继承,而不先显式强制转换
- 为什么显式构造被视为(隐式)缩小转换?
- C++显式类型转换(C 样式强制转换)的强制表示法和static_cast的多种解释
- 整数类型应该显式转换(例如"int"到"无符号")还是只会增加混乱?
- 从双精度转换为整数的显式类型是否始终检查整数溢出?
- 为什么std::string没有(显式)const char*强制转换
- std::vector 范围构造函数可以调用显式转换吗?
- 从 uint8_t 到 int 的隐式转换出错了,当显式转换进展顺利时
- 从 int 显式转换为用户定义的类 c++
- 显式构造函数仍在执行转换
- 自动(toCast)显式转换是否计划在未来C++标准?
- 转换构造函数和运算符都存在且涉及显式性时的行为
- 为什么这里需要显式类型转换
- C++ - 处理隐式/显式强制转换,同时保持灵活的代码
- 为什么C++隐式转换有效,而显式转换无效?
- C++ 如何在不显式强制转换的情况下降级函数调用中的类实例
- 使用分配进行显式转换