有没有办法将文字字符串放入<char ...>模板?</char ...>

时间:2014-06-17 20:21:12

标签: c++ templates c++11

在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">();

最终目标是能够在编译时解析字符串。

1 个答案:

答案 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(尚未测试其他版本)。

Live example

这是一种技术,与其他解决方案不同,它不需要任何宏,并且对字符串的长度没有任何限制。

它从通常的索引助手开始(这在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;