【问题标题】:GCC C++ bug? (T)x matching X::operator const T&() const differs from clang'sGCC C++ 错误? (T)x 匹配 X::operator const T&() const 与 clang 的不同
【发布时间】:2020-02-27 18:45:20
【问题描述】:

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

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

int i = X();

在转换为int 时应该operator T const&amp;() 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 Conversions [class.conv]。其中,15.3.5 说...

函数重载决议 (16.3.3) 选择最佳转换函数来执行转换。

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

从为给定上下文 (16.3.1) 构建的候选函数集合中,选择一组可行函数

这引发了 GCC 是否认为 operator const T&amp;() const 是不可行的候选人,甚至不是候选人的问题。候选有效的要求非常简单:正确数量的参数,并且 “每个参数都应该存在一个隐式转换序列(16.3.3.1),将该参数转换为相应的参数...... ",这里显然是正确的,所以我认为 GCC 一定不能将 operator const T&amp;() const 视为候选者,这将我们带到 16.3.1 候选函数和参数列表 [over.match.funcs],特别是 16.3.1/7:

在候选函数模板的每种情况下,候选函数模板特化是 使用模板参数推导(17.8.3、17.8.2)生成。然后将这些候选人处理为 以通常的方式候选函数。

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

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

【问题讨论】:

标签: c++ gcc c++17 language-lawyer conversion-operator


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-31
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    • 2014-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多