有人可以告诉我C++什么时候需要文字类吗?我对constexpr构造函数和 constexpr 成员
感到有些困惑,我看不出重点是什么。我想看看它的一些实际用途。
另外我想知道一个集合成员函数是否需要是constexpr,即:
constexpr void set_num(int a) { num = a; }
在 C++03 中,此对象具有动态初始化
struct Data {
int i;
int j;
};
Data init_data(); // calculate something
const Data data = init_data();
即当程序启动时,在main
运行之前,将调用该函数并初始化对象。
在 C++11 中,对象可以有常量初始化,静态初始化的一种形式,这意味着它的值是在编译时设置的,并且在程序开始之前被初始化。这对于避免静态初始化顺序失败等非常有用。为了确保类型得到常量初始化,它必须由常量表达式初始化,因此必须有一个constexpr
构造函数,并且在完整表达式中调用的任何函数都必须是constexpr
函数。
该类型Data
是微不足道的,所以它的隐式声明的构造函数是constexpr
构造函数,所以为了使全局data
进行常量初始化,我们只需要做init_data()
一个constexpr
函数:
struct Data {
int i;
int j;
};
constexpr Data init_data(); // calculate something
constexpr Data data = init_data();
文字类型的优点是此类类型可以在其他常量表达式中使用,即在需要编译时常量的上下文中。所以现在我们将data
对象作为编译时常量,我们可以在其他常量表达式中使用它,例如初始化其他编译时常量:
const int i = ::data.i;
我们可以将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
or0x23
或整数类型的编译时常量。在 C++11 中,您可以编写自己的类型,这些类型在其构造函数中具有中等复杂的逻辑(可以在constexpr
函数中表示的任何内容),但仍可用作编译时常量。
另外我想知道一个集合成员函数是否需要是 constexpr,即
constexpr
成员函数是成员函数的一种特殊情况,const
因此它不能修改-mutable
该类型的(非)成员。修改对象的 setter 函数不能是 const。
要成为文字类型,类必须遵循一些规则,包括至少有一个constexpr
构造函数。这并不意味着该类型的所有对象都必须是constexpr
常量,它只是意味着该类型的对象可以是constexpr
常量,如果它们被声明为常量并使用类的constexpr
构造函数之一进行初始化。再次使用该Data
示例,程序中的大多数对象都不是常量:
Data d = { 0, 1 };
d.i = d.i + 5;
因此,如果您添加了一个 setter,一个修改对象的函数,那么只有在该类型的非常量对象上使用它才有意义,并且像任何其他修改类型的函数一样,它不应该是
constexpr 修复了 C++98 中使用数值限制时的问题。在 C++11 之前的表达式,例如
std::numeric_limits<short>::max()
不能用作积分常数,虽然它几乎等于宏INT_MAX
。对于 C++11,这样的表达式被声明为 constexpr,例如,您可以使用它来声明数组或编译时计算(元编程):
std::array<float,std::numeric_limits<short>::max()> a;
类的一大优势constexpr
是可以将它们放入 .ro 数据中,这可以减少可执行文件的大小并提高性能。特别是。对于几何类型,例如或类似的“简单”类型,这非常简洁,因为您也可以摆脱“魔术”数字。参见例如https://www.kdab.com/kdab-contributions-to-qt-5-0-part-4/。