`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



哪个编译器在这里做的事情是正确的?

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.