简体   繁体   English

参数包扩展问题

[英]Parameter pack expansion questions

I managed to solve a previous question about initializing a static char array, asked here: Initializing a static char based on template parameter 我设法解决了有关初始化静态char数组的先前问题,在这里提出了以下问题: 基于模板参数初始化静态char

I don't like the need for a secondary function in my solution: 我不喜欢我的解决方案中需要辅助功能:

//static char arr[N] = {[0]='0', [1]='x', [N-1]='\0',};
// ideally want this, but not currently implemented in g++

template <char... chars>
struct zero_str {};

template <unsigned N, char... chars>
struct seq_gen { using type = typename seq_gen<N-1, '0', chars...>::type; };

template <char... chars>
struct seq_gen<0, chars...> { using type = zero_str<chars...>; };

template <size_t N>
struct zero_gen { using type = typename seq_gen<N-1, '0', '\0'>::type; };

template <>
struct zero_gen<0> { using type = zero_str<'\0'>; };

template<size_t N> using strsize = typename zero_gen<N>::type;

template<typename T, char... chars>
const char* n2hexHelper(T val, zero_str<chars...>)
{
    thread_local static char hexstr[] = {'0', 'x', chars...};
    /* convert to hex */
    return hexstr;
};

template<typename T>
const char* n2hex(T val)
{
    return n2hexHelper<T> (val, strsize<sizeof(T)*2>() );
}

int main()
{
    std::cout << n2hex(1) << std::endl;
    return EXIT_SUCCESS;
}

Instead, I'd prefer not to need the dummy variable passed to the helper function, and be able to do something like this: 相反,我不希望将虚拟变量传递给helper函数,并且能够执行以下操作:

template<typename T, char... chars>
const char* n2HexIdeal(T val)
{
    thread_local static char hexstr[] = {'0', 'x', chars...}; //how to get chars... ?
    /* convert to hex */
    return hexstr;
}

I have two main questions. 我有两个主要问题。 1) is something like my ideal case possible with parameter pack expansions? 1)通过参数包扩展是否可以实现我的理想情况? Or is the only way to force the compiler to deduce my char... is to use it as a function parameter? 还是强制编译器推断出我的字符的唯一方法是将其用作函数参数? 2) I'm not very familiar with template metaprogramming, so I was wondering if there are any glaring faults or idiomatic missteps with my above solution. 2)我对模板元编程不是很熟悉,因此我想知道上面的解决方案是否存在明显的错误或惯用的错误之处。

If you can accept that your helper function is a static method of a class/struct, you can use the partial specialization as follows 如果您可以接受助手函数是类/结构的静态方法,则可以按如下方式使用部分专业化

template <typename, typename>
struct n2hexH;

template <typename T, char ... Chs>
struct n2hexH<T, zero_str<Chs...>>
 {
   static char * func (T const & val)
    {
      thread_local static char hexstr[] = {'0', 'x', Chs...};
      /* convert to hex */
      return hexstr;
    }
 };

Now, your n2hex() function become 现在,您的n2hex()函数变为

template<typename T>
const char* n2hex(T val)
 { return n2hexH<T, strsize<(sizeof(T)<<1U)>>::func(val); }

or you can tranform it in a macro 或者您可以将其转换为宏

#define n2hex(X) n2hexH<decltype(X), strsize<(sizeof(X)<<1U)>>::func(X)

This is doable in C++14. 这在C ++ 14中是可行的。

template<class=void, std::size_t...Is>
auto index_over( std::index_sequence<Is...> ) {
  return [](auto&& f)->decltype(auto) {
    return decltype(f)(f)( std::integral_constant<std::size_t, Is>{}... );
  };
}
template<std::size_t N>
auto index_over( std::integral_constant< std::size_t, N > ={} ) {
  return index_over( std::make_index_sequence<N>{} );
}

These are two helper functions that allow you to expand a bunch of std::size_t compile-time values without a "custom" helper function at each point of use. 这是两个帮助程序函数,使您可以在没有使用“自定义”帮助程序函数的情况下扩展一堆std::size_t编译std::size_t

We can then use them: 然后,我们可以使用它们:

template<typename T>
const char * toStr(T num)
{
  thread_local static
  auto str = index_over<sizeof(T)*3>()
  ([&](auto...Is)->std::array<char, 3+3*sizeof(T)> {
    return {{ '0', 'x',
      (void(Is),'0')...,
      '\0'
    }};
  });
  // do something with str
  (void)num;
  return str.data();
}

to generate and expand our parameter packs inline. 内联生成和扩展我们的参数包。

This requires auto variardic lambdas, which is why it doesn't work in C++11. 这需要自变量lambda,这就是为什么它在C ++ 11中不起作用的原因。

live example . 现场例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM