在构造函数中使用constexpr成员

时间:2018-07-18 15:50:52

标签: c++ c++14 constexpr

我有以下代码:

struct C {
    int var = 3;
};

当我这样使用它时:

constexpr C c;
static_assert(c.var == 3, "");

一切正常,但是,如果我想在constexpr构造器中执行此断言,它将失败:

struct C {
    constexpr C() { static_assert(var == 3, ""); }
    int var = 3;
};

为什么会这样? 在constexpr构造函数中,应该在编译时就知道每个变量,对吧?

2 个答案:

答案 0 :(得分:4)

  

在constexpr构造函数中,应该在编译时就知道每个变量,对吧?

错。

constexpr构造函数是一个函数(方法),可以在编译时(在您的情况下,声明c constexpr)执行,也可以在运行时(例如,声明{ {1}}不是C c2;)。

因此,构造函数内部的constexpr是一个错误,因为在运行时执行构造函数时,编译器无法对其进行检查。

换句话说... 如下使用时

static_assert()

可以编译,因为constexpr C c; static_assert(c.var == 3, ""); 被声明为c,因此constexpr的值是已知的编译时间。

但是

c.var

出现错误,因为C c2; static_assert(c2.var == 3, ""); 的值是未知的编译时间。

写作

c2.var

询问两种情况下都执行constexpr C() { static_assert(var == 3, ""); }

答案 1 :(得分:1)

constexpr函数(无论是ctor,(静态)成员函数还是自由函数)是可以在编译时评估适当假设的函数。

不能保证在编译时会评估任何特定的调用,除非在需要编译时常数的上下文中进行。
因此,在需要编译时常数表达式的情况下,不能使用任何非static constexpr成员。

即使是GCC的__builtin_constant_p(),由于某些原因,它也没有帮助。

http://coliru.stacked-crooked.com/a/2aab3b90335b9d04