【问题标题】:Is this error message correct: non-type template argument is not a constant expression此错误消息是否正确:非类型模板参数不是常量表达式
【发布时间】:2016-04-06 08:06:56
【问题描述】:

以下程序可以使用 GCC 5.2 编译,但不能使用 clang 3.6:

constexpr bool flag();

template <bool b = flag()>
constexpr bool test() 
{ 
    return b;
}

int main() 
{
}

我用 clang 得到的错误信息是:

main.cpp:3:20: error: non-type template argument is not a constant expression
template <bool b = flag()>
                   ^~~~~~
main.cpp:3:20: note: undefined function 'flag' cannot be used in a constant expression
main.cpp:1:16: note: declared here
constexpr bool flag();
               ^
main.cpp:4:16: error: no return statement in constexpr function
constexpr bool test() 
               ^

我的问题是:谁是对的?或者,换句话说:程序是否格式错误?

【问题讨论】:

  • 可以确认,连clang 3.7都不编译。但是,如果您将 return 语句放入 constexpr bool flag(),它会起作用。
  • 我认为这与您关于评估默认模板参数的点的其他问题有关:如果在定义时对它们进行评估,则 clang 无法证明此模板在 [ temp.res]p8
  • 为什么在void函数中有return语句?我还可以确认这在 MSVS 2015 上编译
  • @0x499602D2 对不起,我有点困惑。这个模板当然可以有有效的专业化。所以问题是,您是否可以提供无效的默认模板参数。 CWG 2008CWG 1850 触及了这一点,但我认为它没有得到完全回答。 member templates 中也有类似的问题,表示允许clang 拒绝OP 的程序。
  • 我很高兴我不以编写 C++ 编译器为生。

标签: c++ templates c++11 language-lawyer constexpr


【解决方案1】:

我会说 clang 是对的:

来自标准:

[temp.param] 14.1 #9

9 默认模板参数是在模板参数中 = 之后指定的模板参数 (14.3)。 [...]

和 [temp.arg.nontype] 14.3.2

1 非类型模板参数的模板参数应是模板参数类型的转换常量表达式 (5.20)。

和 [expr.const] 5.20

2 条件表达式 e 是核心常量表达式,除非按照抽象机 (1.9) 的规则对 e 的求值将求值以下表达式之一:

[...]

(2.3) — 调用未定义的 constexpr 函数或未定义的 constexpr 构造函数;

由于flag()已声明但未定义,因此它不是常量表达式,违反了14.3.2。

【讨论】:

    【解决方案2】:

    根据 ISO C++14 标准 5.19.2:

    条件表达式 e 是核心常量表达式,除非 e 的评估,遵循抽象机 (1.9) 的规则, 将评估以下表达式之一:

    • this (5.1.1),除了在作为 e 的一部分计算的 constexpr 函数或 constexpr 构造函数中;
    • 对文字类、constexpr 函数或隐式调用的 constexpr 构造函数以外的函数的调用 一个微不足道的析构函数(12.4)[注:重载解决方案(13.3)照常应用-结束注释];
    • 调用未定义的 constexpr 函数或未定义的 constexpr 构造函数;
    • (...) 块引用

    在定义之前进行的任何 constexpr 函数调用的结果都不是常量表达式。

    最后好像是GCC的bug。

    【讨论】:

    • 我想每个人都同意这一点。不过还有一些额外的问题,主要的问题可能是:是否允许 clang 拒绝这个程序即使从未使用过默认模板参数
    • @FilipRoséen-refp 我知道你必须为你的 smeta 技术处理这个问题,但我不记得这些信息是从哪里来的。是否来自草稿、讨论、缺陷报告……?
    • @dyp 我很确定我在b.atch.se 的其中一个帖子中提到了特定的措辞 - 我目前在地铁上,但可以提供有关此事的详细信息(包括答案​​)我回家了(希望如此)。
    • @FilipRoséen-refp 我所能找到的只是变量模板的默认模板参数(在最近的草稿中)的措辞。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    相关资源
    最近更新 更多