C++ named requirements: LiteralType (since C++11)
From cppreference.net
指定某个类型为
字面类型
。字面类型是
constexpr
变量
的类型,并且可以从
constexpr
函数
中构造、操作和返回这些类型。
注意:标准并未定义以此命名的具名要求。这是由核心语言定义的类型类别。此处将其作为具名要求收录仅为保持一致性。
目录 |
要求
字面类型是以下任意一种:
|
(since C++14) |
-
- 拥有 平凡 (C++20 前) constexpr (C++20 起) 析构函数 ,
- 其所有非静态非变体数据成员和基类均为非易失性字面类型,且
- 满足以下条件之一
| (since C++17) |
注释
即使某个类型的所有constexpr构造函数都被删除、不可访问或无法参与重载决议,该类型仍可能是字面类型。
struct A { constexpr A(int) = delete; char c; }; // A 是字面类型 constexpr A v = std::bit_cast<A>('0'); // C++20 中合法 // v 具有字面类型,因此可以是 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++标准。
| 缺陷报告 | 应用于 | 发布时的行为 | 正确行为 |
|---|---|---|---|
| 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 中移除)
|
检查类型是否为字面类型
(类模板) |