📅  最后修改于: 2023-12-03 14:59:51.575000             🧑  作者: Mango
在C++11中,引入了用户定义字面量(feature test macro为__cplusplus >= 201103L
),这是一种可以自定义表示值的方式。用户定义字面量可以用来扩展C++语言来支持用户自定义类型的字面量,使得操作起来更简单,更直观。
字面量是源代码中的一个固定值。例如在以下的语句中:
int a = 5;
5
就是一个字面量,它代表固定的整数值。
在C++中,有很多内置类型的字面量,例如整数、浮点数、字符以及字符串等等。用户定义字面量则是定义新类型的字面量。
要定义一个用户定义的字面量,我们需要用到字面量操作符。字面量操作符告诉编译器如何处理一个字符串序列。字面量的通用语法为:
operator "" identifier(char);
在这个语法中,operator ""
是字面量操作符的固有的名称。identifier
则是用户定义的字符串序列的名称,而char
则是该字符串序列所使用的字符类型(例如char
, wchar_t
或char16_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个字符。
用户定义字面量是一种非常强大的工具,可以使您的代码更加直观、易读、易于维护。然而,由于其限制,并不是所有情况下都需要使用它。如果您开发代码库,并希望使它易于使用并具有一致的界面,那么用户定义字面量就是一个非常好的方案。