c++ - 使用 constexpr 而不仅仅是静态 const 变量还能提供什么?

标签 c++ c++11 constexpr

据我所知,编译时的计算意味着,在运行时而不是 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/

相关文章:

c++ - C++:在constexpr构造函数中初始化成员数组

C++ - 检测死套接字

c++ - typeid 的成本是多少?

c++ - 静态成员声明为 const 但初始化为 constexpr

c++ - 静态模板化 constexpr 嵌套类成员

c++ - 我应该将分配器作为函数参数传递吗? (我对分配器的误解)

c++ - Quicksort 没有做任何事情,现在陷入了永远的循环

c++ - 如何将 std::string 转换为 boost::gregorian::date?

c++ - 未找到方法 : Templates, 虚拟方法、继承、多态性

c++ - vc++ 不再使用基于范围的语法对简单的 for 循环进行矢量化