我在使用constexpr
时遇到了一些麻烦。本书 C ++ Primer 显示了一行代码:
constexpr int sz = size(); // only size() is a constexpr function
// this code is right
然而,本书没有给出一个具体的例子。所以我自己尝试以下代码:
#include <iostream>
constexpr int fun();
int main()
{
constexpr int f = fun();
std::cout << f << std::endl;
}
constexpr int fun()
{
return 3;
}
但我的编译器说fun()
未定义。
如果我将constexpr
更改为const
,则效果很好,如果我在使用前更改了代码以定义constexpr函数:
#include <iostream>
constexpr int fun()
{
return 3;
}
int main()
{
constexpr int f = fun();
std::cout << f << std::endl;
}
它也很好用。有人可以告诉我为什么吗?
答案 0 :(得分:17)
constexpr
函数在首次使用之前不必定义,但在定义之前进行的任何调用的结果都不是常量表达式。
资料来源:C ++标准草案n4296,第5.20节:
草案3485(第5.19节)中的条件表达式
e
是核心常量表达式,除非根据抽象机器的规则评估e
评估以下表达式之一:
this
,constexpr
函数或constexpr
构造函数除外,e
正在评估;- 为文字类,
constexpr
函数或简单析构函数的隐式调用调用除constexpr
构造函数之外的函数[注意:重载决策应用为 通常 - 结束说明];- 调用未定义的
constexpr
函数或未定义的constexpr
构造函数;- ...
版本:
条件表达式是核心常量表达式,除非它涉及以下之一作为潜在评估的子表达式,但是逻辑AND,逻辑OR和条件的子表达式不考虑未评估的操作[注意:重载操作符调用函数。 - 结束说明]:
this
[注意:在计算常量表达式时,函数调用替换会使用指向类对象的指针替换this
成员函数中每次出现的constexpr
。 - 结束说明];- 为文字类或
constexpr
函数调用constexpr
构造函数以外的函数[注意:过载分辨率照常应用 - 结束注释];- 调用未定义的
constexpr
函数或未定义的constexpr
构造函数- ...
由于标准化之前所做的更改,n2235中的示例int x2 = s. t();
实际上变为有效。但是,constexpr int x2 = s. t();
仍然是错误。
答案 1 :(得分:3)
必须在首次使用之前定义常量表达式函数。请参阅本节paper,4.1节末尾。