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

< cpp‎ | named req
 
 
 

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

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

要求

字面类型是下列之一:

  • 可为 cv 限定的 void (从而 constexpr 函数能返回 void );
(C++14 起)
  • 标量类型;
  • 引用类型;
  • 字面类型的数组;
  • 可有 cv 限定的类类型,并拥有下列全部属性:
  • 拥有平凡 (C++20 前) constexpr (C++20 起)析构函数,
  • 是以下之一
  • 聚合类型,
  • 或拥有至少一个 constexpr 构造函数(可为模板)且非复制或移动构造函数,
(C++17 起)
  • 对于联合体,至少有一个非静态数据成员是非 volatile 字面类型,
  • 对于非联合体,所有非静态数据成员和基类是非 volatile 字面类型。
(C++17 起)
  • 所有非静态数据成员和基类是非 volatile 字面类型。
(C++17 前)

参数

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

#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 << "the number of lowercase letters in \"Hello, world!\" is ";
    constN<countlower("Hello, world!")>(); // 隐式转换成 conststr
}

输出:

the number of lowercase letters in "Hello, world!" is 9


缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR 应用于 出版时的行为 正确行为
CWG 1951 C++11 (类类型)
C++14 (void)
仍不明确 cv 限定的 void 及类类型是否字面类型 它们是

参阅

(C++11)(C++17 中弃用)(C++20 中移除)
检查类型是否为字面类型
(类模板)