在C ++ 11或C ++ 14中是否有办法将文字字符串输入到可变参数模板的参数列表中?例如,我们说我有:
template <char C, char... S>
void GrabFirst()
{
printf("%c %zu\n", C, static_cast<size_t>(sizeof... S));
}
template <char... S>
void MyFunction()
{
GrabFirst<S>();
}
我希望能够以某种形式将文字字符串输入MyFunction。如果C ++ 11在&#34; char&#34;模板参数可以接受它,但它没有:
MyFunction<"meow">();
最终目标是能够在编译时解析字符串。
答案 0 :(得分:4)
我能想到的最好的东西要求你使用类似的东西:
(更新:感谢dyp的评论,使用情况略显冗长,但现在可以在块范围内使用!)
template< char... > struct foo {};
struct hallo { static constexpr const char* str() { return "Hallo"; } };
make< foo, hallo > m;
其中make< foo, hallo >
扩展为foo< 'H', 'a', 'l', 'l', 'o' >
。它是C ++ 11,适用于最新版本的GCC和Clang(尚未测试其他版本)。
这是一种技术,与其他解决方案不同,它不需要任何宏,并且对字符串的长度没有任何限制。
它从通常的索引助手开始(这在C ++ 14中已经可用):
template< std::size_t... Ns >
struct indices
{
using next = indices< Ns..., sizeof...( Ns ) >;
};
template< std::size_t N >
struct make_indices
{
using type = typename make_indices< N - 1 >::type::next;
};
template<>
struct make_indices< 0 >
{
using type = indices<>;
};
现在是主要技术:
constexpr std::size_t length( const char* str )
{
return *str ? ( length( str + 1 ) + 1 ) : 0;
}
template< template< char... > class C,
typename T,
typename = typename make_indices< length( T::str() ) >::type >
struct make_impl;
template< template< char... > class C,
typename T,
std::size_t ... Is >
struct make_impl< C, T, indices< Is... > >
{
using type = C< T::str()[ Is ]... >;
};
template< template< char... > class C, typename T >
using make = typename make_impl< C, T >::type;