constexpr函数是一个常量表达式。内联函数在初始化静态值时是否被视为常量表达式?
constexpr int constexpr_add_one(int x) { return x + 1; } // implies inline
inline int inline_add_one(int x) { return x + 1; }
static const int constexpr_value = constexpr_add_one(0xaaaa0000);
static const int inline_value = inline_add_one(0xbbbb0000);
// Aside:
// static constexpr int another_constexpr_value = constexpr_add_one(0xcccc0000);
// error: call to non-constexpr function ‘int inline_add_one(int)’
// static constexpr int another_inline_value = inline_add_one(0xdddd0000);
volatile int value;
int main() {
value = constexpr_value;
value = inline_value;
}
C ++标准是否提供了常量表达式的定义' (哪个晚上没有' constexpr')?
我使用g ++ 4.8.4
答案 0 :(得分:1)
static
值初始化的规则仅涉及constexpr
而非inline
函数。
constexpr
隐含inline
但inline
并不意味着constexpr
。只需选择下面的constexpr
函数的任何规则,让你的函数打破它。尽管如此,这样的功能仍然可以inline
。
http://en.cppreference.com/w/cpp/language/constexpr
函数声明中使用的constexpr说明符意味着内联。
constexpr函数必须满足以下要求:
- 一定不能虚拟
- 其返回类型必须为LiteralType
- 其每个参数必须为LiteralType
- 存在至少一个参数值,使得函数的调用可以是核心常量的计算子表达式 表达式(对于constexpr函数模板,至少有一个 专业化必须满足这个要求,对于构造者来说,使用 在常量初始化器中就足够了(因为C ++ 14))
- 函数体必须删除或默认,或者只包含以下内容:
- null陈述
- static_assert声明
- 未定义类或枚举的typedef声明和别名声明
- 使用声明
- 使用指令
- 正好一个return语句。 (直到C ++ 14)
- 函数体必须删除或默认,或包含任何语句,除了:
- asm声明
- 一个转到声明
- 带有除case和default之外的标签的声明
- 试用块
- 非文字类型变量的定义
- 静态或线程存储持续时间变量的定义
- 未执行初始化的变量的定义。
- 如果函数是默认的复制/移动赋值,则其所属的类不得具有可变的变体成员您可以 以任何合理的方式制作绝对不是
constexpr
的函数inline
。
电子。 G。 参数不是文字
inline void f1(const std::string&) { }
非文字类型变量的定义
inline void f1() { std::string a; }
试用块
inline void f1() { try { int a = 0; } catch(...) {} }
编辑: 标准确实定义了“常量表达式”。定义相当长。也许你可以在这里查看: http://en.cppreference.com/w/cpp/language/constant_expression