c++ - 指向可变函数模板的指针

标签 c++ templates c++11 function-pointers variadic-templates

我有一个简单的类 A,它提供了一个可变函数模板。此函数使用 A 中的私有(private)数据,但函数本身是公开的。类(class)如下:

class A {
public:

    A() :
    _bla("bla: ") {
    }

    template <class T>
    void bar(const T& value) {
        std::cout << _bla << value << std::endl;
    }

    template <class H, class... T>
    void bar(const H& value, const T&... data) {
        std::cout << _bla << value << std::endl;
        bar(data...);
    }

private:
    const std::string _bla;
};

在一个名为 foo.hpp 的单独文件中,我有一个函数 foo(),它应该能够接收和使用函数 a。 bar() 作为参数:

int main(int argc, char *argv[]) {    
    A a;
    a.bar(1, "two", 3, 4);
    foo(&a.bar);
}

我不太确定从哪里开始,但我尝试了以下方法——但没有用。我怎样才能正确地做到这一点:

template <typename... T>
inline void foo(void (bar *)(const T&...)) {
    unsigned int x(0), y(0), z(0);
    bar(x, y, z);
}

奖励问题:有没有办法不仅调用:

foo(&a.bar);

但也可以调用 foo 并将 a.bar 绑定(bind)到一些参数,例如:

foo(&(a.bar(p1, p2));

我可以简单地将 p1p2 添加到 foo 定义本身,例如:

foo(p1, p2, &a.bar);

但如果我能在之前添加这些参数,在语义上会更符合我的目的。

最佳答案

你不能在没有实例化的情况下传递函数模板的地址,因为它被视为一个完整的重载集(无论模板是否可变)。但是,您可以将它包装在一个通用仿函数中:

struct bar_caller
{
    template<typename... Ts>
    void operator () (A& a, Ts&&... args)
    {
        a.bar(std::forward<Ts>(args)...);
    }
};

然后让你的函数 foo() 定义如下:

template<typename F>
inline void foo(A& a, F f) {
    unsigned int x(0), y(0), z(0);
    f(a, x, y, z);
}

因此您在 main() 中的函数调用将变为:

int main()
{
    A a;
    a.bar(1, "two", 3, 4);
    foo(a, bar_caller());
}

不幸的是,目前在 C++ 中没有办法在不定义单独类的情况下轻松地将重载集包装在仿函数中 - 正如上面对 bar_caller 所做的那样。

编辑:

如果您不想将A 对象直接传递给foo(),您仍然可以让您的bar_caller 封装对必须在其上调用函数 bar()A 对象(只需注意对象的生命周期,这样您就不会使该引用悬空):

struct bar_caller
{
    bar_caller(A& a_) : a(a_) { }

    template<typename... Ts>
    void operator () (Ts&&... args)
    {
        a.bar(std::forward<Ts>(args)...);
    }

    A& a;
};

然后您可以重写 foo()main() 如下:

template<typename F>
inline void foo(F f) {
    unsigned int x(0), y(0), z(0);
    f(x, y, z);
}

int main()
{
    A a;
    a.bar(1, "two", 3, 4);
    foo(bar_caller(a));
}

关于c++ - 指向可变函数模板的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16401811/

相关文章:

c++ - std::unordered_map 中的可能错误

c++ - 如何在 Ubuntu 和 C/C++ 下拔出 USB 设备而不重新启动

c++ - 非模板代码有效时,模板代码无效!

templates - Cakephp 3 多个自定义模板formhelpers

c++ - C++ 11 中 std::is_base_of 的逻辑

c++ - 获取标识符选择未定义

c++ - 使用 system() 执行 ssh 命令

c++ - 有没有办法仅在实例化特定类模板(特化)时调用初始化函数?

c++ - 将 vector<unique_ptr<Derived>> move 到 vector<unique_ptr<Base>>

c++ - std::make_shared 与 throw dtor 和 libc++ 不编译