我正在使用模板元编程来处理字符串操作库。我使用C ++ 11通用常量表达式like in this article在编译时访问原始字符串元素,生成一个包含字符的类型列表,这是元编程库可以处理的类型:
template<typename INDEX>
struct transform_function
{
using result = tml::character<"hello world!"[INDEX::value]>;
};
//tml::for_each returns the set of applications of each element of the specified
//interval on the specified metafunction. In other words, generates a typelist
//which contains each character of the string:
using str = tml::for_each<tml::make_size_t_forward_iterator<0> ,
tml::make_size_t_forward_iterator<sizeof("hello world!")> ,
transform_function>;
using hello2 = tml::concat<str,str>; //hello2 holds "hello world!hello world!"
我编写了一个宏,它从指定的原始字符串生成上面的代码,并用指定的名称命名。例如:
TURBO_STRING_VARIABLE( hello , "hello " );
TURBO_STRING_VARIABLE( world , "world!" );
using hello_world = tml::concat<hello,world>;
现在我想要的是这样一个宏来生成一个有用的字符串,就像这样:
template<typename STRING>
struct to_upper{ ... };
using HELLO_WORLD = typename to_upper<hello_world>::result; //OK, holds "HELLO WORLD!"
using HELLO = typename to_upper<ANONYMOUS_STRING("hello")>; //HELLO
我的for_each
方法不起作用,因为我无法在模板argumment传递的上下文中定义类型,但我在想一种lambda元函数将转换函数直接写入argumment。登记/>
我知道Boost.MPL有这样的东西使用占位符,但我认为不能在这个上下文中使用,因为我在一个与模板无关的上下文中使用参数(数组的索引运算符)并且无法应用占位符技巧。
还有其他方法可以实现这一目标吗?
答案 0 :(得分:1)
在本文中,描述了使用最大字符串长度来实现ANONYMOUS_STRING
的方法。这应该是一般没问题的。只需将100作为最大值,并在字符串较长时断言。用户可以通过连接较短的字符串来创建更长的字符串。有100个字符,你通常有很长的行,无论如何都需要打破它们(考虑终端窗口中源代码的可读性)。
concat<
ANONYMOUS_STRING("Hello "),
ANONYMOUS_STRING("World "),
ANONYMOUS_STRING("!")
>
使用此代码,可以以可读的方式生成更长的字符串。
一般问题是字符串文字不能是模板参数,你不能在你想到的点内部创建一个类:
template<class T>
struct f{};
using g=f<struct { /* some types and data */ }>; // does not work
方法是在这一点实例化另一个模板:
using g=f<std::integral_constant<char, 'x'>>; // does work
所以我认为你必须创建一个宏,对于小字符串来说是大的,对于大字符串来说是小的。这就是Abel Sinkovics和Dave Abrahams描述它的方式。一个很好的效果是你可以用更好的TURBO_STRING_VARIABLE( hello , "hello " );
using hello = ANONYMOUS_STRING("hello");