在初始值设定项列表中展开可变参数失败

Expand variadic arguments in initializer list fails

我尝试创建一个简单的程序,我想在其中创建未来参数的向量。 我创建了一个包装函数,用于提交 lambda 函数并在向量内部存储未来对象

我使用了一个中间步骤,在该步骤中我使用可变参数创建了一个 initiliazer_list。但是编译失败。我尝试使用调用函数来将元素推送到向量中,但也无法编译

代码如下

#include <iostream>
#include <thread>
#include <future>
#include <functional>
#include <cstdlib>
#include <chrono>
#include <initializer_list>
using namespace std;
using FunctPtr  = function<int(int, int) >;
using FutureInt = future<int>;
using AsyncVector = vector<FutureInt>;
AsyncVector asyncVec;

template<typename... TemplatePtr>
void submit(TemplatePtr... pFunc)
{
  auto initList {pFunc... };
  for (auto & element : initList)
  {
      asyncVec.emplace_back(async(launch::async, element,4,5));
  }
}


int main()
{
    int a;
    int b;
    auto addPtr = [](int x, int y)->int 
    {
        std::cout << "add :" << x + y << std::endl;
        return x + y; 
    };
    auto multPtr = [](int x, int y)->int
    {
        std::cout << "mult :" << x * y << std::endl;
        return x * y;
    };
   // submit(add,4,5);
    submit(addPtr, multPtr);
    for (auto & v : asyncVec)
    {
        std::cout << "Wait for " << v.get() << std::endl;
    }
}

是的,它们是不同的类型,所以不能轻易在同一个初始化列表中。

您最好的选择可能应该是:

  1. 要么将它们全部推入同一个折叠表达式中的 asyncVec
template<typename... TemplatePtr>
void submit(TemplatePtr... pFunc)
{
  (asyncVec.emplace_back(async(launch::async, std::move(pFunc), 4, 5)), ...);
}
  1. 或者,如果它们都具有相同的签名,则对它们进行类型擦除,例如将它们保存在 std::function.
  2. 的数组中
template<typename... TemplatePtr>
void submit(TemplatePtr... pFunc)
{
  for (auto &&element: {std::function<int(int, int)>(std::move(pFunc))...})
  {
      asyncVec.emplace_back(async(launch::async, std::move(element), 4, 5));
  }
}

(我已经明确指定了函数签名,尽管编译器应该能够推断出它。)

  1. 或者,如果所有闭包都是无捕获的并且具有相同的签名,则在调用 submit 时只需将它们转换为相同的类型:
using SameType = int (*)(int, int);
submit(static_cast<SameType>(addPtr), static_cast<SameType>(mulPtr));

这样您的原始 submit 应该可以正常工作。