命名空间
变体
操作

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

来自 cppreference.com
 
 
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 字面量类可以具有易失性数据成员 不允许
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 中已删除)
检查类型是否为字面量类型
(类模板) [编辑]