什么时候应该在C++;? 有人能告诉我C++中的文字课是什么时候吗? 我对constexpr构造函数、constexpr成员感到有点困惑,我看不出重点是什么。我想看看它的实际用途

什么时候应该在C++;? 有人能告诉我C++中的文字课是什么时候吗? 我对constexpr构造函数、constexpr成员感到有点困惑,我看不出重点是什么。我想看看它的实际用途,c++,class,c++11,constexpr,C++,Class,C++11,Constexpr,我还想知道集合成员函数是否需要是constexpr,即: constexpr void set_num(int a) { num = a; } constexpr修复了C++98中使用数字限制时的一个问题。C++11之前的表达式,如 std::numeric_limits<short>::max() constexpr类的一大优点是它们可以被放入.ro数据中,这可以减少可执行文件的大小并提高性能。特别是对于几何类型,例如,或类似的“简单”类型,这是非常整洁的,因为您还可以摆脱“神

我还想知道集合成员函数是否需要是constexpr,即:

constexpr void set_num(int a) { num = a; }

constexpr修复了C++98中使用数字限制时的一个问题。C++11之前的表达式,如

std::numeric_limits<short>::max()

constexpr
类的一大优点是它们可以被放入.ro数据中,这可以减少可执行文件的大小并提高性能。特别是对于几何类型,例如,或类似的“简单”类型,这是非常整洁的,因为您还可以摆脱“神奇”数字。例如,请参见C++03中的..

。此对象具有动态初始化

i、 e.当程序启动时,在
main
运行之前,将调用函数并初始化对象

在C++11中,对象可以具有常量初始化,这是静态初始化的一种形式,意味着它的值在编译时设置,并且在程序开始之前初始化。这有助于避免其他问题。为了确保类型得到常量初始化,它必须由常量表达式初始化,因此必须具有
constexpr
构造函数,并且在完整表达式中调用的任何函数都必须是
constexpr
函数

类型
Data
很简单,因此其隐式声明的构造函数是
constepr
构造函数,因此要使全局
Data
进行常量初始化,我们只需要使
init_Data()
成为
constepr
函数:

struct Data {
  int i;
  int j;
};
constexpr Data init_data();  // calculate something
constexpr Data data = init_data();
文字类型的优点是,此类类型可以在其他常量表达式中使用,即在需要编译时常量的上下文中使用。现在我们有了
data
对象作为编译时常量,我们可以在其他常量表达式中使用它,例如初始化其他编译时常量:

const int i = ::data.i;
Data d = { 0, 1 };
d.i = d.i + 5;
对于带有类内初始值设定项的静态数据成员,我们可以使用
Data
类型:

struct MoreData {
  static constexpr Data zerozero = Data{};  // OK, Data is a literal type
};
如果
Data
不是文本类型,我们必须编写:

struct MoreData {
  static const Data zerozero;
};

// in moredata.cc
const Data MoreData::zerozero = Data{};
然后,只看到头的代码不知道
MoreData::zerozero
的值,并且不能在编译时优化中使用它

因此,“文字类型”规则的优点是允许您定义可以在常量表达式中使用的新类类型。在C++03中,常量表达式中只能使用极少数类型,例如整数,例如
1
0x23
或整数类型的编译时常量。在C++11中,您可以编写自己的类型,这些类型的构造函数中可以有适度复杂的逻辑(可以用
constexpr
函数表示的任何类型),但仍然可以用作编译时常量

我还想知道集合成员函数是否需要是constexpr,即

constepr
成员函数是
const
成员函数的特例,因此它不能修改该类型的(非
-可变的
)成员。修改对象的setter函数不能是常量

要成为文字类型,类必须遵循一些规则,包括至少有一个
constexpr
构造函数。这并不意味着该类型的所有对象都必须是
constepr
常量,它只是意味着该类型的对象可以是
constepr
常量,如果它们被声明为常量,并且使用类'
constepr
构造函数之一初始化。要再次使用
数据
示例,程序中的大多数对象都不是常量:

const int i = ::data.i;
Data d = { 0, 1 };
d.i = d.i + 5;

因此,如果您添加了一个setter,一个修改对象的函数,那么只有在该类型的非常量对象上使用它才有意义,并且与任何其他修改该类型的函数一样,它不应该是

,您不能修改编译时对象。您的
set\u num
成员似乎试图修改类的成员。如果
set_num
声明为constexpr,则无法修改该对象,因此您的赋值将无效。我没有遇到过使用类的constexpr实例的特殊情况,但无论如何我很少使用constexpr。原则上,当您想将几个相关的constexpr值和函数组合在一起时,您可以创建一个类。@VaughnCato,您是对的,
constexpr
成员函数不能修改对象,但这与任何其他
const
成员函数一样,不是因为对象是“编译时对象”。你可以有文字类型的可变对象。对,就像我在下面的回答中说的:这并不意味着该类型的所有对象都必须是
constexpr
常量,这只是意味着该类型的对象可以声明为
constexpr
constants。实际上,日常使用中的
constexpr
对于此类常量返回函数来说最有意义,当然,这只是
constexpr
及其用法和含义的一半真相(也只是实际问题的一半答案)。