📜  C++中的用户定义字面量(1)

📅  最后修改于: 2023-12-03 14:59:51.575000             🧑  作者: Mango

C++中的用户定义字面量

在C++11中,引入了用户定义字面量(feature test macro为__cplusplus >= 201103L),这是一种可以自定义表示值的方式。用户定义字面量可以用来扩展C++语言来支持用户自定义类型的字面量,使得操作起来更简单,更直观。

字面量的定义

字面量是源代码中的一个固定值。例如在以下的语句中:

int a = 5;

5就是一个字面量,它代表固定的整数值。

在C++中,有很多内置类型的字面量,例如整数、浮点数、字符以及字符串等等。用户定义字面量则是定义新类型的字面量。

字面量操作符

要定义一个用户定义的字面量,我们需要用到字面量操作符。字面量操作符告诉编译器如何处理一个字符串序列。字面量的通用语法为:

operator "" identifier(char);

在这个语法中,operator ""是字面量操作符的固有的名称。identifier则是用户定义的字符串序列的名称,而char则是该字符串序列所使用的字符类型(例如char, wchar_tchar16_t)。

下面是一个简单的例子,定义了一个将字符串转化为小写的字面量操作符,使用起来类似于字符串方法 (.lower()):

#include <iostream>
#include <string>

std::string operator "" _to_lower(const char* str, std::size_t len)
{
    std::string lower;
    lower.reserve(len);
    for (std::size_t i = 0; i < len; ++i) {
        lower.push_back(std::tolower(str[i]));
    }
    return lower;
}

int main()
{
    std::cout << "HELLO WORLD!"_to_lower << '\n';
    return 0;
}

在这个例子中,_to_lower作为字面量操作符。它接收一个字符串指针和它的长度,并返回一个新的std::string,该string中包含了该字符串的小写版本。这样一来,我们就可以使用字符串字面量"HELLO WORLD!"开始一条语句,然后在字面量后面紧跟着我们定义的操作符,就可以将其转换为小写形式。输出为:

hello world!
重载类型后缀

除了重载字符串字面量操作符,我们也可以重载字面量的类型后缀。类型后缀是一个字面量的末尾后缀,可以用来指定字面量的类型。例如,在以下语句中:

auto distanceInMiles = 10.5f;

字面量10.5f被指定为浮点字面量。

我们可以定义新的类型后缀并为其提供不同的类型解释。

#include <iostream>

struct Centimeters {
    constexpr Centimeters(double cm) : value(cm) {}
    double value;
};

constexpr Centimeters operator "" _cm(long double cm)
{
    return Centimeters(static_cast<double>(cm));
}

int main()
{
    std::cout << (10.0_cm).value << " cm\n";
    return 0;
}

在这个例子中,我们定义了一个名为Centimeters的结构体,并创建了一个名为_cm的函数,它是一个用户定义的字面量后缀。该函数接收一个long double类型的参数,并返回一个Centimeters类型的值。这样一来,我们可以定义一个浮点字面量,紧随其后的是自定义后缀_cm

输出如下:

10 cm
限制

尽管用户定义字面量为C++提供了一种非常强大的扩展方式,但是使用它们也有一些限制。

第一个限制是字面量操作符的命名。字面量操作符的名称必须以operator ""开始,然后接着的是一个有效的C++标识符。例如:

operator "" _foobar(char);

在这个例子中,标识符为_foobar

另一个限制是类型后缀的长度。类型后缀的长度必须小于或等于16个字符。

结论

用户定义字面量是一种非常强大的工具,可以使您的代码更加直观、易读、易于维护。然而,由于其限制,并不是所有情况下都需要使用它。如果您开发代码库,并希望使它易于使用并具有一致的界面,那么用户定义字面量就是一个非常好的方案。