传递可变参数函数作为参数 [英] Passing a variadic function as argument

查看:104
本文介绍了传递可变参数函数作为参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下工作代码:

#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 结构如下:

I want to now generalize the Foo struct like so:

#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不能被推论。我该如何实现呢?

But I get a compile error (from GCC 4.9.2) that F cannot be deduced. How do I achieve this?

推荐答案

foo 是重载族,因此 foo 是不明确的。

(即使 foo< int,int> 是,因为它也可能具有其他类型。)

foo is a family of overloads, and so the foo is ambiguous.
(even foo<int, int> is, as it may have additional type too).

您可以强制按如下方式使用预期的类型函数:

You may force expected type function as follow:

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 包装到一个类中:

An alternative is to wrap function foo into a class:

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';
    }

};

并保持实施:

< a href = http://ideone.com/EJ5kz1 rel = nofollow>实时演示

这篇关于传递可变参数函数作为参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆