命名空间
变体
操作

C++ 命名要求: LiteralType (自 C++11 起)

来自 cppreference.cn
< cpp‎ | named req
 
 
C++ 命名要求
 

指定类型为字面类型。字面类型是 constexpr 变量 的类型,它们可以被构造、操作,并从 constexpr 函数 中返回。

注意:标准未定义以此名称命名的需求。这是一个由核心语言定义的类型类别。此处将其作为命名要求包含仅为保持一致性。

目录

[编辑] 要求

字面类型是以下任何一种

  • 可能是 cv 限定的 void(以便 constexpr 函数可以返回 void);
(自 C++14 起)
  • 具有 平凡的(直至 C++20)constexpr(自 C++20 起) 析构函数
  • 其所有非静态非变体数据成员和基类均为非易失性字面类型,并且
  • 是以下之一
(自 C++17 起)
  • 没有 变体成员,或
  • 至少有一个非易失性字面类型的变体成员,
  • 没有 变体成员,或
  • 至少有一个非易失性字面类型的变体成员,
  • 具有至少一个 constexpr(可能是模板)构造函数(不是复制或移动构造函数)的类型。

[编辑] 注释

即使类型的所有 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 中移除)
检查类型是否为字面类型
(类模板) [编辑]