[英]What more does using constexpr gives instead of just static const variables?
据我所知,在编译时计算意味着,在运行时而不是constexpr函数会有const值(根据定义,因为它们已经被计算)。 触及函数(它们已经计算,因此,它只是函数类型的变量),它接触变量(它就像静态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)我可以理解没有参数的构造函数是否为constexpr。 是的,它是一些const状态,可以在编译时计算并在将来使用,也许更快。 但为什么构造函数有参数? 对象体将在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
不能用作模板参数,但假设向量是由int
的,你可以这样做:
SomeClass<myGlobalVec.x()> anObject;
1:如果参数在编译时已知,则可以在编译时调用获取参数的constexpr
构造函数。 这可能对封装状态很有用,这与我们在运行时使用对象而不是原始值的原因相同。
2,3:类似地,如果原始源对象也是编译时值,则可以在编译时复制constexpr
对象。
4,5: constexpr
访问器可以在运行时和编译时调用。 运行时性能并不直接相关,除了constexpr
方法隐式内联并且行为良好(不包含某些未定义的行为),因此可能更适合优化。
对象体将在Stack或Heap上,(...)
这至多是不相关的,最坏的是错误的。 在C ++抽象机器中,对象将位于某个存储位置。 在真实的机器中,对象将在编译器认为合适的任何地方,并且在任何地方甚至可能无处可去 。
我们不知道我们会把哪些参数放在那里,它是什么?
如果我们使用具有参数的常量表达式的构造函数初始化对象,则初始化表达式也将是常量表达式。 常量表达式是特殊的,因为它们是可以在某些特定上下文中使用的唯一种类的表达式,如数组大小或模板参数。 除了作为常量表达式计数之外,没有constexpr
,这与正常初始化之间没有区别 。
我们怎样才能在编译时计算出未知对象的复制?
与之前相同:如果我们使用常量表达式作为源初始化副本,则副本也将是常量表达式。 请注意, constexpr
只是关于计算为常量表达式的事物。 它不是关于何时进行评估 。
我想知道它可以用什么。 仅针对在编译时计算状态的对象?
见上文:)主要目的是允许在需要常量表达式的上下文中使用这些对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.