Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++11 是否可以定义模板参数包数组_C++11_Templates_Variadic Templates_Variadic Functions_Template Meta Programming - Fatal编程技术网

C++11 是否可以定义模板参数包数组

C++11 是否可以定义模板参数包数组,c++11,templates,variadic-templates,variadic-functions,template-meta-programming,C++11,Templates,Variadic Templates,Variadic Functions,Template Meta Programming,可能重复: 与上面的问题类似,我想进一步探讨这个问题并存储一个可变数组 template<size_t N, typename... Args> void foo(Args(&...args)[N]) { Args[N]... args2; // compilation error } 将被调用且不会产生任何副作用: int A[N] = { 1, 2, 3, 4, 5 }; int B[N] = { 2, 2, 2, 2, 2 }; applyAsDoubled(p

可能重复:

与上面的问题类似,我想进一步探讨这个问题并存储一个可变数组

template<size_t N, typename... Args>
void foo(Args(&...args)[N]) {
  Args[N]... args2; // compilation error
}
将被调用且不会产生任何副作用:

int A[N] = { 1, 2, 3, 4, 5 };
int B[N] = { 2, 2, 2, 2, 2 };

applyAsDoubled(printAdded, A, B);

将打印6、8、10、12、14,其中
A
B
未发生突变。只是为了澄清一下,函数
doublerMutation()
是一个伪函数,用于表示一个会导致参数突变且无法重写的函数。

我建议您使用一个C++14解决方案,该解决方案应适用于C++11,并替换
std::index_sequence
std::make_index_sequence

我建议,对于
applyasDouble()
,只需调用一个helper函数,并在数组的数量上传递
std::index\u序列

template <typename F, std::size_t N, typename ... As>
void applyAsDoubled (F f, As(&...as)[N])
 { applyAsDoubledH(f, std::make_index_sequence<sizeof...(As)>{}, as...); }
观察对
getStdArray()的调用

下面是一个完整的工作示例

#include <tuple>
#include <array>
#include <iostream>
#include <type_traits>

template <std::size_t I, std::size_t N, typename ... Args>
void doublerMutationH (std::tuple<std::array<Args, N>...> & tpl)
 {
   for ( auto ui { 0u } ; ui < N ; ++ui )
      std::get<I>(tpl)[ui] *= 2;
 }

template <std::size_t N, typename ... Args, std::size_t ... Is>
void doublerMutation (std::tuple<std::array<Args, N>...> & tpl,
                      std::index_sequence<Is...> const &)
 {
   using unused = int[];

   (void) unused { 0, (doublerMutationH<Is>(tpl), 0)... };
 }

template <typename T, std::size_t N, std::size_t ... Is>
std::array<T, N> getStdArray (T(&a)[N], std::index_sequence<Is...> const &)
 { return { { a[Is]... } }; }

template <typename F, std::size_t ... Is, std::size_t N, typename ... Args>
void applyAsDoubledH (F f, std::index_sequence<Is...> const & is,
                      Args(&...args)[N])
 {
   auto isn { std::make_index_sequence<N>{} };

   std::tuple<std::array<Args, N>...> tpl { getStdArray(args, isn)... };

   doublerMutation(tpl, is);

   for (auto ui { 0u } ; ui < N ; ++ui )
      f(std::get<Is>(tpl)[ui]...);
 }

template <typename F, std::size_t N, typename ... As>
void applyAsDoubled (F f, As(&...as)[N])
 { applyAsDoubledH(f, std::make_index_sequence<sizeof...(As)>{}, as...); }

int main ()
 {
   int  A[] = { 1, 2, 3, 4, 5 };
   long B[] = { 2, 2, 2, 2, 2 };

   auto printSum = [](auto const & ... as)
    {   
      using unused = int[];

      typename std::common_type<decltype(as)...>::type  sum {};

      (void)unused { 0, (sum += as, 0)... };

      std::cout << "the sum is " << sum << std::endl;
    };

   applyAsDoubled(printSum, A, B);
 }
以及
printSum()
lambda测试函数,如下所示

template <std::size_t N, typename ... Args, std::size_t ... Is>
void doublerMutation (std::tuple<std::array<Args, N>...> & tpl,
                      std::index_sequence<Is...> const &)
 { ( doublerMutationH<Is>(tpl), ... ); }
auto printSum = [](auto const & ... as)
 { std::cout << "the sum is " << (as + ...) << std::endl; };
auto printSum=[](auto const&…as)

{std::C++11或C++14/C++17一定行吗?C++14/C++17并不理想。但是,我想听听那里的解决方案。我知道这是反对的,但我真的很感激你所做的大量工作。我真的很震惊。@MichaelChoi-我喜欢模板元编程。添加了一些C++17简化。只是一个简单的问题你的C++ 17示例:双元映射的第二个参数是怎么命名的?你怎么引用?@ MichaelChoi——不仅在C++ 17示例中,也在C++ 14版本中;那个参数只用于允许编译器推断<代码> is…<代码>变量列表;它本身没有使用。在C++中,你不能给一个未使用的参数加上名字。这避免了恼人的“参数未使用”类型警告。
template <std::size_t I, std::size_t N, typename ... Args>
void doublerMutationH (std::tuple<std::array<Args, N>...> & tpl)
 {
   for ( auto ui { 0u } ; ui < N ; ++ui )
      std::get<I>(tpl)[ui] *= 2;
 }

template <std::size_t N, typename ... Args, std::size_t ... Is>
void doublerMutation (std::tuple<std::array<Args, N>...> & tpl,
                      std::index_sequence<Is...> const &)
 {
   using unused = int[];

   (void) unused { 0, (doublerMutationH<Is>(tpl), 0)... };
 }
#include <tuple>
#include <array>
#include <iostream>
#include <type_traits>

template <std::size_t I, std::size_t N, typename ... Args>
void doublerMutationH (std::tuple<std::array<Args, N>...> & tpl)
 {
   for ( auto ui { 0u } ; ui < N ; ++ui )
      std::get<I>(tpl)[ui] *= 2;
 }

template <std::size_t N, typename ... Args, std::size_t ... Is>
void doublerMutation (std::tuple<std::array<Args, N>...> & tpl,
                      std::index_sequence<Is...> const &)
 {
   using unused = int[];

   (void) unused { 0, (doublerMutationH<Is>(tpl), 0)... };
 }

template <typename T, std::size_t N, std::size_t ... Is>
std::array<T, N> getStdArray (T(&a)[N], std::index_sequence<Is...> const &)
 { return { { a[Is]... } }; }

template <typename F, std::size_t ... Is, std::size_t N, typename ... Args>
void applyAsDoubledH (F f, std::index_sequence<Is...> const & is,
                      Args(&...args)[N])
 {
   auto isn { std::make_index_sequence<N>{} };

   std::tuple<std::array<Args, N>...> tpl { getStdArray(args, isn)... };

   doublerMutation(tpl, is);

   for (auto ui { 0u } ; ui < N ; ++ui )
      f(std::get<Is>(tpl)[ui]...);
 }

template <typename F, std::size_t N, typename ... As>
void applyAsDoubled (F f, As(&...as)[N])
 { applyAsDoubledH(f, std::make_index_sequence<sizeof...(As)>{}, as...); }

int main ()
 {
   int  A[] = { 1, 2, 3, 4, 5 };
   long B[] = { 2, 2, 2, 2, 2 };

   auto printSum = [](auto const & ... as)
    {   
      using unused = int[];

      typename std::common_type<decltype(as)...>::type  sum {};

      (void)unused { 0, (sum += as, 0)... };

      std::cout << "the sum is " << sum << std::endl;
    };

   applyAsDoubled(printSum, A, B);
 }
template <std::size_t N, typename ... Args, std::size_t ... Is>
void doublerMutation (std::tuple<std::array<Args, N>...> & tpl,
                      std::index_sequence<Is...> const &)
 { ( doublerMutationH<Is>(tpl), ... ); }
auto printSum = [](auto const & ... as)
 { std::cout << "the sum is " << (as + ...) << std::endl; };