GCC C++ 错误? (T)x 匹配 X::operator const T&() const 不同于 clang 的

GCC C++ bug? (T)x matching X::operator const T&() const differs from clang's

我遇到了 GCC 和 clang 之间的差异(在 godbolt 测试的大范围版本 - 都有相同的差异)与转换运算符匹配。现在使用 Barry 的较短复制代码 - 也可在 godbolt.

获得
struct X {
    template <typename T>
    operator T const&() const;
};

int i = X();

转换为 int 时应该 operator T const&() const 匹配(clang 说是/GCC 需要 operator T() const 以避免:

<source>:6:9: error: cannot convert 'X' to 'int' in initialization
        6 | int i = X();
          |         ^~~

C++17 标准的相关部分是 15.3 转换 [class.conv]。其中,15.3.5 表示...

Function overload resolution (16.3.3) selects the best conversion function to perform the conversion.

...这几乎是最重要的。 16.3.3 是 最佳可行函数 [over.match.best] 的部分,但通常与 16.3.2 可行函数 [over.match.viable] 组合使用。该标准似乎没有明确说明 16.3.2 是否适用于此处,但假设适用,我们在 16.3.2.1 中有:

From the set of candidate functions constructed for a given context (16.3.1), a set of viable functions is chosen

这引发了一个问题,即 GCC 是否认为 operator const T&() const 一个不可行的候选人,或者甚至不是一个候选人。候选人有效的要求非常简单:正确的参数数量,"there shall exist for each argument an implicit conversion sequence (16.3.3.1) that converts that argument to the corresponding parameter...",这在这里显然是正确的,所以我相信 GCC 不能考虑 operator const T&() const 一个候选函数,它将我们带到 16.3.1 候选函数和参数列表 [over.match.funcs],特别是 16.3.1/7:

In each case where a candidate is a function template, candidate function template specializations are generated using template argument deduction (17.8.3, 17.8.2). Those candidates are then handled as candidate functions in the usual way.

假设可以使用 int 参数类型调用 template <typename T> void f(const T&);,我认为 GCC 应该将转换运算符视为有效候选者,就像 clang 一样。

虽然我很感激确认/想法。如果大家同意,我将针对 GCC 提出错误报告。

这是一个 GCC 错误 pointed out by T.C.