C++ 命名要求: LiteralType (自 C++11 起)
来自 cppreference.cn
指定类型为字面类型。字面类型是 constexpr
变量 的类型,它们可以被构造、操作,并从 constexpr
函数 中返回。
注意:标准未定义以此名称命名的需求。这是一个由核心语言定义的类型类别。此处将其作为命名要求包含仅为保持一致性。
目录 |
[编辑] 要求
字面类型是以下任何一种
|
(自 C++14 起) |
- 具有 平凡的(直至 C++20)constexpr(自 C++20 起) 析构函数,
- 其所有非静态非变体数据成员和基类均为非易失性字面类型,并且
- 是以下之一
(自 C++17 起) |
[编辑] 注释
即使类型的所有 constexpr 构造函数都被删除、不可访问或无法参与重载解析,该类型也可以是字面类型。
struct A { constexpr A(int) = delete; char c; }; // A is a literal type constexpr A v = std::bit_cast<A>('0'); // OK in C++20 // v has literal type and thus can be constexpr
[编辑] 示例
扩展字符串字面量的字面类型
运行此代码
#include <cstddef> #include <iostream> #include <stdexcept> class conststr // conststr is a literal type { const char* p; std::size_t sz; public: template<std::size_t N> constexpr conststr(const char(&a)[N]) : p(a), sz(N - 1) {} constexpr char operator[](std::size_t n) const { return n < sz ? p[n] : throw std::out_of_range(""); } constexpr std::size_t size() const { return sz; } }; constexpr std::size_t count_lower(conststr s) { std::size_t c{}; for (std::size_t n{}; n != s.size(); ++n) if ('a' <= s[n] && s[n] <= 'z') ++c; return c; } // An output function that requires a compile-time constant N, for testing template<int N> struct constN { constN() { std::cout << N << '\n'; } }; int main() { std::cout << "The number of lowercase letters in \"Hello, world!\" is "; constN<count_lower("Hello, world!")>(); // the string literal is implicitly // converted to conststr }
输出
The number of lowercase letters in "Hello, world!" is 9
[编辑] 缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。
DR | 应用于 | 已发布行为 | 正确行为 |
---|---|---|---|
CWG 1453 | C++11 | 字面类可以具有 volatile 数据成员 | 不允许 |
CWG 1951 | C++11 C++14 |
不清楚 cv 限定的 void (C++14) 和类类型 (C++11) 是否为字面类型 |
它们是 |
CWG 2096 | C++11 | 对于联合类型为字面类型,其所有非 静态数据成员必须是字面类型 |
只需要一个非静态数据 成员是 |
CWG 2598 | C++11 | 对于联合类型为字面类型,它必须具有 至少一个非静态数据成员 |
它可以没有非 静态数据成员 |
[编辑] 参见
(C++11)(在 C++17 中弃用)(在 C++20 中移除) |
检查类型是否为字面类型 (类模板) |