Dan*_*Dan 9 c++ templates variadic-templates c++11
我试图了解C++ 11中的可变参数模板.我有一个类,它基本上是一个包装器std::array.我希望能够将函数对象(理想情况下为lambdas)传递给成员函数,然后将std::array传递的元素作为函数对象的参数.
我用a static_assert来检查参数的数量是否与数组的长度相匹配,但我想不出将元素作为参数传递的方法.
这是代码
#include <iostream>
#include <array>
#include <memory>
#include <initializer_list>
using namespace std;
template<int N, typename T>
struct Container {
template<typename... Ts>
Container(Ts&&... vs) : data{{std::forward<Ts>(vs)...}} {
static_assert(sizeof...(Ts)==N,"Not enough args supplied!");
}
template< typename... Ts>
void doOperation( std::function<void(Ts...)>&& func )
{
static_assert(sizeof...(Ts)==N,"Size of variadic template args does not match array length");
// how can one call func with the entries
// of data as the parameters (in a way generic with N)
}
std::array<T,N> data;
};
int main(void)
{
Container<3,int> cont(1,2,3);
double sum = 0.0;
auto func = [&sum](int x, int y, int z)->void{
sum += x;
sum += y;
sum += z;
};
cont.doOperation(std::function<void(int,int,int)>(func));
cout << sum << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题(如代码中所示)是如何以一种通用的方式将条目传递data给函数?funcN
奖金问题:是否有可能取消std::function主要的难看的转换并直接传入lambda?
And*_*owl 13
鉴于众所周知的指数基础设施:
namespace detail
{
template<int... Is>
struct seq { };
template<int N, int... Is>
struct gen_seq : gen_seq<N - 1, N - 1, Is...> { };
template<int... Is>
struct gen_seq<0, Is...> : seq<Is...> { };
}
Run Code Online (Sandbox Code Playgroud)
您可以通过以下方式重新定义类模板:
template<int N, typename T>
struct Container {
template<typename... Ts>
Container(Ts&&... vs) : data{{std::forward<Ts>(vs)...}} {
static_assert(sizeof...(Ts)==N,"Not enough args supplied!");
}
template<typename F>
void doOperation(F&& func)
{
doOperation(std::forward<F>(func), detail::gen_seq<N>());
}
template<typename F, int... Is>
void doOperation(F&& func, detail::seq<Is...>)
{
(std::forward<F>(func))(data[Is]...);
}
std::array<T,N> data;
};
Run Code Online (Sandbox Code Playgroud)
这是一个实例.
请注意,您不需要构造一个std::function对象main():std::function可以从lambda隐式构造.但是,您根本不需要std::function在这里使用,可能会产生不必要的运行时开销.
在上面的解决方案中,我只是让可调用对象的类型成为模板参数,可以由编译器推导出来.
| 归档时间: |
|
| 查看次数: |
3380 次 |
| 最近记录: |