pax*_*blo 9 c++ templates user-defined-literals variadic-templates c++11
我一直在研究C++ 11的一些新功能,并且对其中的一些非常印象深刻,特别是用户定义的文字.
这些允许您定义表单的文字,999_something其中something控制999对生成文字所做的操作.所以不必再使用:
#define MEG * 1024 * 1024
int ten_meg = 10 M;
Run Code Online (Sandbox Code Playgroud)
我认为大量实现下划线会很好,比如1_000_000_blahPerl的可读性,虽然Perl在某种程度上可读的想法对我来说似乎很幽默:-)
它对于像1101_1110_b和的二进制值也很方便0011_0011_1100_1111_b.
显然,由于_字符,这些将需要是原始模式类型,处理C字符串,我没关系.
我无法弄清楚的是如何根据操作数大小提供不同的类型.例如:
1101_1110_b
Run Code Online (Sandbox Code Playgroud)
应该给出一个char(假设char当然是8位),而:
0011_0011_1100_1111_b
Run Code Online (Sandbox Code Playgroud)
将提供16位类型.
我可以从文字运算符函数operator""本身(通过计数数字字符)获取操作数的长度,但返回类型似乎固定到函数,所以我不能基于此返回不同的类型.
这可以用一个单一的后缀来完成_b用户定义类型框架内,还是需要求助于除了手动拆分类型(_b8,_b16等等),并提供主要功能重复?
您需要知道字符串的大小,并且实现这一目标的唯一方法是使用参数包sizeof....您应该能够使用可变参数模板实现您想要的功能operator"":
#include <cstdint>
#include <type_traits>
template<char... String>
auto operator "" _b()
-> typename std::conditional<sizeof...(String) <= 8,
uint8_t,
typename std::conditional<sizeof...(String) <= 16,
uint16_t,
uint32_t
>::type
>::type
{
// Do whatever you want here
}
Run Code Online (Sandbox Code Playgroud)
这是一个测试用例:
int main()
{
auto a = 10000001_b;
auto b = 100000001_b;
std::cout << std::boolalpha;
std::cout << std::is_same<decltype(a), uint8_t>::value << "\n"; // true
std::cout << std::is_same<decltype(b), uint16_t>::value << "\n"; // true
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,该解决方案无法处理数字分隔符.而且,std::conditional机器非常难看.你也许可以一起想更好的boost::mpl::vector,boost::mpl::at和一些算术运算.