C++ 具名要求:字面类型 (LiteralType)

来自cppreference.com
< cpp‎ | named req
 
 
C++ 具名要求
基础
类型属性
库所属
容器
容器元素
(C++11)

迭代器
流 I/O
格式化
(C++20)
随机数
(C++11)    
并发
(C++11)
(C++11)
范围
其他
LiteralType
(C++11)
(C++11)


 

指明一个类型为字面类型。字面类型是 constexpr 变量所拥有的类型,且能通过 constexpr 函数构造、操作及返回它们。

注意:标准中并没有定义具有这个名字的具名要求。这是核心语言所定义的一种类型类别。将它作为具名要求包含于此只是为了保持一致性。

要求

字面类型是下列之一:

  • 可有 cv 限定的 void(这样 constexpr 函数可以返回 void);
(C++14 起)
  • 拥有平凡 (C++20 前)constexpr (C++20 起) 析构函数,
  • 是以下之一:
(C++17 起)
  • 没有变体成员,或者
  • 至少有一个具有无 volatile 限定的字面类型的变体成员
  • 没有变体成员,或者
  • 至少有一个具有无 volatile 限定的字面类型的变体成员
  • 拥有至少一个 constexpr 构造函数(可以是模板)且非复制或移动构造函数的类型

参数

扩展字符串字面量的字面类型:

#include <iostream>
#include <stdexcept>
 
class conststr
{
    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 countlower(conststr s, std::size_t n = 0,
                                             std::size_t c = 0)
{
    return n == s.size() ? c :
        s[n] >= 'a' && s[n] <= 'z' ? countlower(s, n + 1, c + 1) :
                                     countlower(s, n + 1, c);
}
 
// 要求编译时常量的输出函数,测试需要
template<int n>
struct constN
{
    constN() { std::cout << n << '\n'; }
};
 
int main()
{
    std::cout << "\"Hello, world!\" 中小写字母的个数是 ";
    constN<countlower("Hello, world!")>(); // 隐式转换成 conststr
}

输出:

"Hello, world!" 中小写字母的个数是 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 中移除)
检查类型是否为字面类型
(类模板)