在 C++ 中,constexpr 关键字用于声明常量表达式(即在编译时求值的表达式)。为了能被声明为 constexpr,变量必须具有字面量类型(literal type)或引用类型(reference type)。
字面量类型的要求
- 基本数据类型:如 int, char, bool, double 等基本类型是字面量类型。
- 枚举类型:枚举类型是字面量类型。
- 数组类型:如果元素类型是字面量类型,则数组是字面量类型。
- 类类型:类可以是字面量类型,但必须满足以下条件:
- 所有非静态数据成员都是字面量类型。
- 必须有一个 constexpr 构造函数。
- 析构函数是默认的或被删除的。
- 类不能是多态的(即不能有虚函数)。
- 类不能是联合体。
错误示例1
想要达到通过传入一个类型给GetString
,GetString
返回这个类型的字符串,尝试代码如下:
template <typename T>
stryct GetString;template <>
stryct GetString<int32_t>
static constexpr std::string value = "int32_t";
因为std::string
不是字面类型,所以上述代码会报错:a constexpr variable must have a literal type or a reference type
错误示例2
class NonLiteralType {int value;
public:NonLiteralType(int v) : value(v) {}
};constexpr NonLiteralType obj(10); // 错误:NonLiteralType 不是字面量类型
在这个例子中,NonLiteralType 不是字面量类型,因为它的构造函数不是 constexpr,尽管它的数据成员是字面量类型。
class LiteralType {int value;
public:constexpr LiteralType(int v) : value(v) {}constexpr int getValue() const { return value; }
};constexpr LiteralType obj(10); // 正确:LiteralType 是字面量类型
在这个修改后的例子中,LiteralType 被正确地定义为字面量类型,因为它的构造函数和访问成员函数都是 constexpr,并且其数据成员是字面量类型。