使用内联函数初始化静态值是否使用常量表达式进行初始化?

时间:2016-06-11 10:45:00

标签: c++

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

1 个答案:

答案 0 :(得分:1)

static值初始化的规则仅涉及constexpr而非inline函数。

constexpr隐含inlineinline并不意味着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