如果我的班级是字面的班级,那么将我的类的对象声明为constexpr是多余的

If my class is a literal class then is it redundant to declare an object of my class as constexpr?

本文关键字:我的 声明 对象 多余 constexpr 如果      更新时间:2023-10-16

我有一个constexpr类调试:

struct Debug {
  constexpr Debug(bool a, bool b, bool c) : a(a), b(b), c(c) {}
  bool a, b, c;
  constexpr bool get() const { return a; }
};
int main() {
  Debug dbg(true, false, false); // is dbg constexpr object?
  constexpr Debug dbg2(0, 0, 0); // is constexpr redundant here?
}

您可以看到 dbg是一个constexpr对象,因为它是使用constexpr构造函数初始化的,因此,如果我通过constexpr限定了它,这有什么意义?

  • 我不知道dbgdbg2之间的区别。谢谢。

有一个主要区别:只能在需要常数表达式的情况下使用dbg2。例如,考虑允许任意非类型模板参数的即将到来的C 20功能:

template <Debug> void f() { }

使用上述定义,f<dgb2>()将编译,而f<dgb>()则不会。

f<dgb>();
<source>:7:29: note:   template argument deduction/substitution failed:
<source>:13:12: error: the value of 'dbg' is not usable in a constant expression
   13 |   foo<dbg>();  // ERROR
      |            ^
<source>:10:9: note: 'dbg' was not declared 'constexpr'
   10 |   Debug dbg(true, false, false); // is dbg constexpr object?

godbolt.org上的实时示例


这在C 11中也很重要。您将能够说:

template <bool> void g() { }
g<dgb2.a>();

但不是:

g<dgb.a>();

godbolt.org上的实时示例

两个变量如何不同的简单证明:

struct Debug {
  constexpr Debug(bool a, bool b, bool c) : a(a), b(b), c(c) {}
  bool a, b, c;
  constexpr bool get() const { return a; }
};
int main() {
  Debug dbg(true, false, false); // dbg is not a constant
  constexpr Debug dbg2(0, 0, 0); // constexpr makes this a constant expression
  // *** Begin demo ***
  dbg.a = false;
  //dbg2.a = false; //< error: assignment of member 'Debug::a' in read-only object
  // *** End demo ***
}

可以更改dbg的值,而dbg2的值不能。

要获得一个恒定表达式的Debug对象,您同时需要构造函数中的constexpr限定符(以将Debug对象标记为恒定表达式(和 constexpr fififier在变量声明中(以标记该对象标记该对象作为恒定表达式(。