我在
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;
}
但是 clang 3.1 说:
未定义的函数“fun”不能在常量表达式中使用
如果我将
constexpr
更改为 const
,它效果很好,如果我在使用之前更改代码以定义 constexpr 函数:
#include <iostream>
constexpr int fun()
{
return 3;
}
int main()
{
constexpr int f = fun();
std::cout << f << std::endl;
}
效果也很好。有人可以告诉我为什么吗?
constexpr
函数在首次使用之前不必定义,但是在定义之前进行的任何调用的结果都不是常量表达式。
来源:C++ 标准草案 n4296,第 5.20 节:
A 条件表达式
是一个核心常量表达式,除非对e
的求值遵循抽象机的规则,将求值以下表达式之一:e
,除了作为this
的一部分进行评估的constexpr
函数或constexpr
构造函数;e
- 对文字类的
构造函数以外的函数的调用、constexpr
函数或普通析构函数的隐式调用 [注意:重载解析应用为 通常 — 尾注];constexpr
- 调用未定义的
函数或未定义的constexpr
构造函数;constexpr
- ...
3485 草案版本(第 5.19 节):
A 条件表达式 是核心常量表达式,除非它涉及以下内容之一作为潜在计算的子表达式,但不考虑未计算的逻辑 AND、逻辑 OR 和条件运算的子表达式 [ 注意:重载运算符调用函数。 — 尾注]:
[ 注意:计算常量表达式时,函数调用替换会将this
成员函数中每次出现的this
替换为指向类对象的指针。 — 尾注];constexpr
- 对文字类或
函数的constexpr
构造函数之外的函数的调用 [注意:重载解析照常应用 - 尾注];constexpr
- 调用未定义的
函数或未定义的constexpr
构造函数constexpr
- ...
n2235 中的示例
int x2 = s. t();
实际上由于标准化之前所做的更改而变得有效。然而,constexpr int x2 = s. t();
仍然是一个错误。
常量表达式函数必须在首次使用之前定义。请参阅这篇论文,第 4.1 节末尾。