传递变元函数作为参数
Passing a variadic function as argument
考虑一下这个工作代码:
#include <iostream>
#include <utility>
#include <array>
template <typename... Args>
void foo (Args&&... args) {
const auto v = {args...};
for (auto x : v) std::cout << x << ' '; std::cout << 'n';
}
template <typename> struct Foo;
template <std::size_t... Is>
struct Foo<std::index_sequence<Is...>> {
template <typename Container>
static void execute (const Container& v) {
foo(v[Is]...);
}
};
template <std::size_t N>
void fooArray (const std::array<int, N>& a) {
Foo<std::make_index_sequence<N>>::execute(a);
}
int main() {
fooArray<6>({0,1,2,3,4,5}); // 0 1 2 3 4 5
}
我现在想将Foo
结构概括为:
#include <iostream>
#include <utility>
#include <array>
template <typename... Args>
void foo (Args&&... args) {
const auto v = {args...};
for (auto x : v) std::cout << x << ' '; std::cout << 'n';
}
template <typename> struct Foo;
template <std::size_t... Is>
struct Foo<std::index_sequence<Is...>> {
template <typename Container, typename F> // *** Modified
static void execute (const Container& v, F f) {
f(v[Is]...);
}
};
template <std::size_t N>
void fooArray (const std::array<int, N>& a) {
Foo<std::make_index_sequence<N>>::execute(a, foo);
}
int main() {
fooArray<6>({0,1,2,3,4,5});
}
但我得到了一个编译错误(来自GCC 4.9.2(,无法推导F。我该如何做到这一点?
foo
是一个重载族,因此foo
是不明确的
(甚至foo<int, int>
也是,因为它也可能具有附加类型(。
您可以强制执行以下预期类型的功能:
template <std::size_t... Is>
struct Foo<std::index_sequence<Is...>> {
template <typename Container>
static void execute (const Container& v, void (*f)(decltype(v[Is])&...)) {
f(v[Is]...);
}
};
实例
另一种选择是将函数foo
封装到一个类中:
class FooCaller
{
public:
template <typename... Args>
void operator () (Args&&... args) const {
const auto v = {args...};
for (auto x : v) std::cout << x << ' '; std::cout << 'n';
}
};
并保持您的实施:
实时演示
模板不是一个单一的东西。不能将模板函数作为函数或对象传递。现在,重载集的名称(比如foo
(可以在特定上下文中解析为模板函数的单个实例(在您调用它的地方,或者将它转换为函数指针(,这可能就是欺骗您的原因。
如果你想把整个过载集作为一个对象来处理,你可以通过来近似它
struct foo_f{
template<class...Args>
auto operator()(Args&&...args)const->
decltype(foo(std::declval<Args>()...))
{ return foo(std::forward<Args>(args)...); }
};
并且现在CCD_ 7的实例将CCD_。用foo_f{}
代替foo
。
在C++14中,或者:
[](auto&&...args)->decltype(auto){return foo(decltype(args)(args)...);}
是一个lambda,其行为与上面的foo_f
非常相似。
相关文章:
- 将可变参数函数的参数封装在类实例中
- QML 使用带有参数C++函数
- 使用可变参数函数作为模板参数
- 如何在C++中伪造虚拟可变参数函数模板?
- 为什么可变参数函数不适用于模板
- C++ std::functional 中的可变参数函数模板
- 可变参数函数指针的定义对于VxWorks spyLib来说不清楚
- 使用可变参数函数覆盖具有不同函数签名的虚函数
- 考虑引用和常量的可变参数函数包装器
- 使用可变参数函数将整数和/或整数数组放入单个 int 数组中
- 在可变参数函数中转发特定范围的参数
- 通过引用传递参数;函数返回类型是否必须为 VOID?
- 使用带有一个参数函数的递归找到数字的平方
- 可变参数函数模板不能很好地使用 std::function 作为参数
- 多个可变参数函数的单个模板参数包?
- 参数数据类型未知的可变参数函数
- 可变参数函数参数包扩展
- 使用模板可变参数函数将多个参数传递给另一个函数
- 对可变参数函数的递归调用的链接器错误
- 通过像printf这样的可变参数函数传递一个带有常量字符*转换函数的类