在定义失败之前使用constexpr函数

ice*_*y96 27 c++

我遇到了一些麻烦constexpr.C++ Primer一书显示了一行代码:

  constexpr int sz = size(); // only size() is a constexpr function
                             // this code is right
Run Code Online (Sandbox Code Playgroud)

然而,这本书没有给出一个具体的例子.所以我自己尝试以下代码:

#include <iostream>
constexpr int fun();
int main()
{
    constexpr int f = fun();
    std::cout << f << std::endl;
}
constexpr int fun()
{
    return 3;
}
Run Code Online (Sandbox Code Playgroud)

但我的编译器说fun()是未定义的.

如果我constexpr改成const,它运行良好,如果我在使用之前更改我的代码以定义constexpr函数:

#include <iostream>
constexpr int fun()
{
    return 3;
}
int main()
{
    constexpr int f = fun();
    std::cout << f << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

它也很好用.有人可以告诉我为什么吗?

Ben*_*igt 17

constexpr函数不具有它的第一次使用之前进行定义,但是定义之前作出的任何调用的结果是不是一个常量表达式.

资料来源:C++标准草案n4296,第5.20节:

条件表达式 e是一个核心常量表达式除非的评价e,如下所述抽象机的规则,将评估下列表达式之一:

  • this,除了在作为一部分进行评估的 constexpr 函数或constexpr构造函数 中e;
  • 除了constexpr文本类,constexpr函数或普通析构函数的隐式调用的构造函数之外的函数的调用[注意:过载分辨率照常应用 - 结束注释];
  • 调用未定义的constexpr 函数 或未定义的 constexpr 构造函数;
  • ...

草案3485(第5.19节)的版本:

条件表达式是一个核心常量表达式除非它涉及以下作为一个潜在的评价子表达式中的一个,但不被评估不被认为是逻辑与,逻辑OR,和条件操作的子表达式[注:重载运算符调用功能. - 结束说明]:

  • this[注意:在计算常量表达式时,函数调用替换会使用指向类对象的指针替换成员函数this中的每个匹配项 constexpr. - 结束说明];
  • 除了constexpr 文字类或constexpr函数的构造 函数之外的函数的调用 [注意:过载分辨率照常应用 - 结束注释];
  • 调用未定义的constexpr函数或未定义的constexpr构造函数
  • ...

int x2 = s. t();由于标准化之前所做的更改,n2235中的示例实际上变为有效.但是,constexpr int x2 = s. t();仍然是一个错误.

  • @kvorobiev:我引用草稿,因为它是公开的。该规则较早引入了很多草案,并且是官方标准的一部分。 (2认同)