我有以下代码:
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
构造函数中,应该在编译时就知道每个变量,对吧?
答案 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()
,由于某些原因,它也没有帮助。