Ben*_*n H 3 c++ templates stl variadic-templates c++11
为了保持通用和简单,请说我有一个整数的std :: vector,例如:
std::vector<int> v;
Run Code Online (Sandbox Code Playgroud)
现在,我想知道的是,是否有可能从v中取n(其中n是编译时已知的常量)值并将它们传递给任意函数?我知道这对于可变参数模板是可行的:
template<typename... T>
void pass(void (*func)(int, int, int), T... t) {
func(t...);
}
Run Code Online (Sandbox Code Playgroud)
然后我们希望'pass'被调用正好3个整数.细节并不重要.我想知道的是,以下是某种可行的方式:
void pass(void (*func)(int, int, int), std::vector<int> &t) {
auto iter = t.begin();
func((*iter++)...);
}
Run Code Online (Sandbox Code Playgroud)
哪里......被用作可变参数模板?基本上,我问我是否可以
这可能与C++ 11一起使用吗?注意到我需要这个在MSVC v120/VS2013上工作.
这绝对是可能的,但你无法确定在编译时这样做的安全性.正如WhozCraig所说,这是因为向量缺少编译时的大小.
我仍然试图获得我的模板元编程翅膀,所以我可能做了一些不寻常的事情.但这里的核心思想是让一个函数模板以向量中的下一个项目递归调用自身,直到它构建了一个带有所需参数的参数包.一旦有了,就很容易将它传递给相关函数.
这里核心的实现是apply_first_n,它接受一个目标std::function<R(Ps...)>,一个向量和一个参数包Ts....什么时候Ts...比Ps...它更短的包装; 一旦它的大小相同,它就会将它传递给函数.
template <typename R, typename... Ps, typename... Ts>
typename std::enable_if<sizeof...(Ps) == sizeof...(Ts), R>::type
apply_first_n(std::function<R(Ps...)> f, const std::vector<int> &v, Ts&&... ts)
{
if (sizeof...(Ts) > v.size())
throw std::out_of_range("vector too small for function");
return f(std::forward<Ts>(ts)...);
}
template <typename R, typename... Ps, typename... Ts>
typename std::enable_if<sizeof...(Ps) != sizeof...(Ts), R>::type
apply_first_n(std::function<R(Ps...)> f, const std::vector<int> &v, Ts&&... ts)
{
const int index = sizeof...(Ps) - sizeof...(Ts) - 1;
static_assert(index >= 0, "incompatible function parameters");
return apply_first_n(f, v, *(std::begin(v) + index), std::forward<Ts>(ts)...);
}
Run Code Online (Sandbox Code Playgroud)
你可以这样称呼,例如apply_first_n(std::function<int(int, int)>(f), v);.在 实例中,make_fn只是使转换std::function更容易,并且ProcessInts是一个方便的测试功能.
我想知道如何避免使用std::function和修复任何其他存在的严重低效问题.但我要说这证明它是可能的.
作为参考,我把上面的方法进一步处理set,vector,tuple,和initializer_list,以及其他符合正确的接口,它们.删除std::function似乎需要func_infotraits类,以及几个重载.因此,虽然这个扩展的实例肯定更加通用,但我不确定我会把它称为更好.