如何将模板方法作为模板参数传递?

时间:2017-02-06 17:10:36

标签: c++

我想将模板方法作为模板参数传递。

我不明白为什么会收到此错误:

no known conversion for argument 1 from '<unresolved overloaded function type>' to 'void (B::*&&)(int&&, double&&)

以下是代码:

struct A {
    template <class Fn, class... Args>
    void f(Fn&& g, Args&&... args) {
        g(std::forward<Args>(args)...);
    }
};

struct B {
    template <class... Args>
    void doSomething(Args&&... args) {}

    void run() {
        A a;
        a.f(&doSomething<int, double>, 1, 42.); // error here
    }
};

int main() {
    B b;
    b.run();
    return 0;
}

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

错误的根本原因是您需要一个对象来调用成员函数。但是,使用当前代码,错误并不是那么简单。

将呼叫网站更改为

a.f(&B::doSomething<int, double>, 1, 42.)

你会看到更好的错误:

  

错误:必须使用'。'或' - &gt; '来调用'g中的指针指向成员函数   (...)',例如'(... - &gt; * g)(...)'

答案 1 :(得分:1)

doSomething是一个成员函数,因此,如果没有您想要执行的对象,则无法调用它

g(std::forward<Args>(args)...);
^
where is the instance?

对此的一个解决方案是将doSomething包裹在lambda中:

a.f([](B& instance, int a, int b) { instance.doSomething(a, b); }, *this, 1, 42.);

如果你可以使用C ++ 17,你也可以使用std::invoke

template <class Fn, class... Args>
void f(Fn&& g, Args&&... args) {
    std::invoke(g, std::forward<Args>(args)...);
}

然后调用f

a.f(&B::doSomething<int, double>, this, 1, 42.);