使用函数参数使用常量表达式作为模板参数:哪个编译器是正确的?

Gui*_*cot 5 c++ templates language-lawyer constexpr c++20

我有这段代码:

template <int V>
struct Constant {
    constexpr operator int() const noexcept { return V; }
};


template <class T, int N>
struct Array { };

auto function(auto s) -> Array<int, s + s> {
    return {};
}

auto const a = function(Constant<3>{});
Run Code Online (Sandbox Code Playgroud)

让我最悲伤的是,似乎只有 Clang 接受这个代码。

哪个编译器是正确的,为什么?

Bar*_*rry 5

我相信 clang 在这里是正确的。为 gcc打开#114124 。

请注意,gcc 和 MSVC 都接受以下等效公式:

auto function(auto s) {
    return Array<int, s+s>{};
}
Run Code Online (Sandbox Code Playgroud)

只是他们不允许在返回类型中使用参数。

s+s但与在函数体中写入常量表达式不会违反[expr.const]/5的任何规则一样,尾随返回类型中也不会违反任何规则。我们同样没有读取任何内容(即此类程序失败的常见原因是因为我们正在尝试对常量求值器未知的值进行左值到右值的转换),因为转换函数 is 和intdoes constexpr'不要依赖任何数据。

  • @463035818_is_not_an_ai 该陈述是正确的:函数参数不是 constexpr。然而在这种情况下,我们没有读取参数的值 - 我们使用它的(无状态)constexpr 转换函数到“int”。 (3认同)
  • @user12002570 该程序的格式并不错误,并且格式错误的程序无论如何都不是关闭问题的有效理由。 (2认同)