据我所知,编译时的计算意味着,在运行时而不是 constexpr 函数,将有 const 值(根据定义,因为它们已经被计算)。 涉及到函数(已经计算好了,所以,就相当于函数类型的变量),涉及到变量(就相当于static const变量),类也是如此。
我看到 constexpr 函数的一个优点:例如,如果在 ANSI C 中,我必须有 5 个定义,也许逻辑上统一,现在我可以编写一个这样的函数并使用它而不是 5 个定义,能够编写逻辑操纵一组 constexpr 函数返回值。因此,结果我有相同的 5 个值集,但现在我在逻辑上描述了它们,编写了这样的函数。
但是我觉得我理解错了,因为我看到这样的例子:
class vec3 {
union {
struct {
float _x, _y, _z;
};
float _v[3];
};
public:
constexpr vec3(): _x(0), _y(0), _z(0) {} //
constexpr vec3(float x, float y, float z): _x(x), _y(y), _z(z) {}(1)
constexpr vec3(const vec3&) = default; // (2)
vec3 &operator=(const vec3&) = default; // (3)
constexpr float x() { return _x; } // (4)
constexpr float y() { return _y; }
constexpr float z() { return _z; }
constexpr const float *v() { return _v; } // (5)
float *v() { return _v; }
};
(1) 不带参的constructor是constexpr我能理解。是的,它是一些 const 状态,可以在编译时计算并在将来使用,也许更快。但是为什么构造函数有参数呢? Object body会在Stack或Heap上,我们不知道我们会把哪些参数放在那里,是为了什么?
(2, 3) 同样在这里,这是干嘛的?我们如何在编译时计算未知对象的复制?
(4, 5) 不知道有什么用。仅针对在编译时计算哪个状态的对象?或者从 Heap 或 Stack 调用某些对象(将在运行时创建)的值可能会花费很多,而这会以某种方式加快速度?
最佳答案
您忽略了这样一个事实,即在成员函数和构造函数中使用 constexpr
并不意味着它们总是在编译时执行。他们只是在可能的情况下这样做。
为清楚起见,举几个例子:
constexpr vec3 myGlobalVec{1,2,3}; // uses vec3(x,y,z) in compile time
constexpr vec3 copyOfGlobalVec = myGlobalVec; // uses copy constructor in compile time
void foo(int n) {
vec3 my(n,n,n); // uses the same constructor, but invoked in runtime
// ...
}
这同样适用于其余的构造函数:关键点在于,对于 constexpr
限定的函数和构造函数,如果完整的参数列表包含常量表达式(并且如果手头的对象是常量表达式), 那么结果也将是一个常量表达式。
constexpr
getter 的优点是可以获取常量表达式的属性,以便在只允许使用常量表达式的情况下使用。 float
不能用作模板参数,但假设 vector 由 int
组成,您可以这样做:
SomeClass<myGlobalVec.x()> anObject;
关于c++ - 使用 constexpr 而不仅仅是静态 const 变量还能提供什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24740914/