繁体   English   中英

使用constexpr而不仅仅是静态const变量还有什么呢?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM