`auto x = type{...}` 初始化语法和 `explicit` 转换运算符 - clang 与 gcc
`auto x = type{...}` initialization syntax and `explicit` conversion operator - clang vs gcc
给定此代码 (在 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) 拒绝编译代码出现以下错误
error: cannot convert 'X' to 'int' in initialization
clang++
(测试版本:4、3.8、3.6) 愉快地编译了代码片段。
哪个编译器在这里做的事情是正确的?
cppreference 似乎暗示 auto var = type{...}
语法应该触发显式转换。
使用http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/n4606.pdf
我认为 g++ 是错误的。
8.6.4 第 3.7 条规定:
— Otherwise, if the initializer list has a single element of type E
and either T is not a reference type or its referenced type is
reference-related to E, the object or reference is initialized from
that element (by copy-initialization for copy-list-initialization, or
by direct-initialization for direct-list-initialization); if a
narrowing conversion (see below) is required to convert the element to
T, the program is ill-formed.
意味着在这种非class类型的情况下使用直接初始化,这导致我们进入8.6条款17.7:
— Otherwise, if the source type is a (possibly cv-qualified) class
type, conversion functions are considered. The applicable conversion
functions are enumerated (13.3.1.5), and the best one is chosen
through overload resolution (13.3). The user-defined conversion so
selected is called to convert the initializer expression into the
object being initialized. If the conversion cannot be done or is
ambiguous, the initialization is ill-formed.
最后 13.3.1.5 指出显式和隐式转换都被考虑用于直接初始化:
— The conversion functions of S and its base classes are considered.
Those non-explicit conversion functions that are not hidden within S
and yield type T or a type that can be converted to type T via a
standard conversion sequence (13.3.3.1.1) are candidate functions. For
direct-initialization, those explicit conversion functions that are
not hidden within S and yield type T or a type that can be converted
to type T with a qualification conversion (4.5) are also candidate
functions. Conversion functions that return a cv-qualified type are
considered to yield the cv-unqualified version of that type for this
process of selecting candidate functions. Conversion functions that
return “reference to cv2 X” return lvalues or xvalues, depending on
the type of reference, of type “cv2 X” and are therefore considered to
yield X for this process of selecting candidate functions.
给定此代码 (在 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) 拒绝编译代码出现以下错误error: cannot convert 'X' to 'int' in initialization
clang++
(测试版本:4、3.8、3.6) 愉快地编译了代码片段。
哪个编译器在这里做的事情是正确的?
cppreference 似乎暗示 auto var = type{...}
语法应该触发显式转换。
使用http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/n4606.pdf 我认为 g++ 是错误的。
8.6.4 第 3.7 条规定:
— Otherwise, if the initializer list has a single element of type E and either T is not a reference type or its referenced type is reference-related to E, the object or reference is initialized from that element (by copy-initialization for copy-list-initialization, or by direct-initialization for direct-list-initialization); if a narrowing conversion (see below) is required to convert the element to T, the program is ill-formed.
意味着在这种非class类型的情况下使用直接初始化,这导致我们进入8.6条款17.7:
— Otherwise, if the source type is a (possibly cv-qualified) class type, conversion functions are considered. The applicable conversion functions are enumerated (13.3.1.5), and the best one is chosen through overload resolution (13.3). The user-defined conversion so selected is called to convert the initializer expression into the object being initialized. If the conversion cannot be done or is ambiguous, the initialization is ill-formed.
最后 13.3.1.5 指出显式和隐式转换都被考虑用于直接初始化:
— The conversion functions of S and its base classes are considered. Those non-explicit conversion functions that are not hidden within S and yield type T or a type that can be converted to type T via a standard conversion sequence (13.3.3.1.1) are candidate functions. For direct-initialization, those explicit conversion functions that are not hidden within S and yield type T or a type that can be converted to type T with a qualification conversion (4.5) are also candidate functions. Conversion functions that return a cv-qualified type are considered to yield the cv-unqualified version of that type for this process of selecting candidate functions. Conversion functions that return “reference to cv2 X” return lvalues or xvalues, depending on the type of reference, of type “cv2 X” and are therefore considered to yield X for this process of selecting candidate functions.