2017-02-06 5 views
0

私はテンプレートの引数としてテンプレートメソッドを渡したいと思います。テンプレート引数としてテンプレートメソッドを渡すにはどうすればよいですか?

私はこのエラーを取得していますなぜ私は理解していない:

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

任意のアイデア:

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

をここにコードがありますか?

答えて

1

エラーの根本原因は、メンバー関数を呼び出すオブジェクトが必要なことです。しかし、現在のコードでは、エラーはそれほど簡単ではありません。

変更が

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

にサイトを呼び出して、あなたがより良いのエラーが表示されます。

error: must use '.' or '->' to call pointer-to-member function in 'g (...)', e.g. '(... ->* g) (...)'

+0

だから私がする必要がありますstd :: invokeを使用しますか? – infiniteLoop

+1

@mikeDundeeいつでもラムダを使うことができます:) – Rakete1111

1

doSomethingはあなたがいる、など、それはオブジェクトなしで呼び出すことはできません、メンバー関数です。しようとしている

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

この解決策の1つはラップすることですを呼び出したときに

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

と::ラムダで:あなたがC++ 17を使用することができる場合

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

、あなたもstd::invokeを使用することができ

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

ありがとう。あなたの答えをアップアップしますが、SergeyAは速く答えました。 – infiniteLoop

関連する問題