(不完全)constexpr 模板参数的要求
Requirements for (not-quite-) constexpr template arguments
GCC (5.3.0) 和 Clang (3.8.0) 都认为这是有效代码:
constexpr std::integral_constant<size_t, 0> n{};
std::get<n>(std::make_tuple(123));
然而,他们不同意这一点:
std::integral_constant<size_t, 0> n;
std::get<n>(std::make_tuple(123));
Clang 可以接受,但 GCC 报告 "the value of 'n' is not usable in a constant expression"/“'n' 未声明 [=22=]”。
谁的行为符合标准?
Clang 是对的,尽管它最终取决于您的库实现。该标准本身并不禁止在常量表达式中为非 const
(expr
) 对象调用 constexpr
函数;只有使用该对象的成员才会有问题(请参阅 [expr.const]/(2.7.3))。由于转换运算符肯定只是 returns 0
,因此它可能是 GCC 错误(在考虑错误消息时也具有暗示性)。
GCC (5.3.0) 和 Clang (3.8.0) 都认为这是有效代码:
constexpr std::integral_constant<size_t, 0> n{};
std::get<n>(std::make_tuple(123));
然而,他们不同意这一点:
std::integral_constant<size_t, 0> n;
std::get<n>(std::make_tuple(123));
Clang 可以接受,但 GCC 报告 "the value of 'n' is not usable in a constant expression"/“'n' 未声明 [=22=]”。
谁的行为符合标准?
Clang 是对的,尽管它最终取决于您的库实现。该标准本身并不禁止在常量表达式中为非 const
(expr
) 对象调用 constexpr
函数;只有使用该对象的成员才会有问题(请参阅 [expr.const]/(2.7.3))。由于转换运算符肯定只是 returns 0
,因此它可能是 GCC 错误(在考虑错误消息时也具有暗示性)。