在初始值设定项列表中展开可变参数失败
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;
}
}
是的,它们是不同的类型,所以不能轻易在同一个初始化列表中。
您最好的选择可能应该是:
- 要么将它们全部推入同一个折叠表达式中的
asyncVec
。
template<typename... TemplatePtr>
void submit(TemplatePtr... pFunc)
{
(asyncVec.emplace_back(async(launch::async, std::move(pFunc), 4, 5)), ...);
}
- 或者,如果它们都具有相同的签名,则对它们进行类型擦除,例如将它们保存在
std::function
. 的数组中
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));
}
}
(我已经明确指定了函数签名,尽管编译器应该能够推断出它。)
- 或者,如果所有闭包都是无捕获的并且具有相同的签名,则在调用
submit
时只需将它们转换为相同的类型:
using SameType = int (*)(int, int);
submit(static_cast<SameType>(addPtr), static_cast<SameType>(mulPtr));
这样您的原始 submit
应该可以正常工作。
我尝试创建一个简单的程序,我想在其中创建未来参数的向量。 我创建了一个包装函数,用于提交 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;
}
}
是的,它们是不同的类型,所以不能轻易在同一个初始化列表中。
您最好的选择可能应该是:
- 要么将它们全部推入同一个折叠表达式中的
asyncVec
。
template<typename... TemplatePtr>
void submit(TemplatePtr... pFunc)
{
(asyncVec.emplace_back(async(launch::async, std::move(pFunc), 4, 5)), ...);
}
- 或者,如果它们都具有相同的签名,则对它们进行类型擦除,例如将它们保存在
std::function
. 的数组中
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));
}
}
(我已经明确指定了函数签名,尽管编译器应该能够推断出它。)
- 或者,如果所有闭包都是无捕获的并且具有相同的签名,则在调用
submit
时只需将它们转换为相同的类型:
using SameType = int (*)(int, int);
submit(static_cast<SameType>(addPtr), static_cast<SameType>(mulPtr));
这样您的原始 submit
应该可以正常工作。