2016-02-10 3 views
6

次のコードをコンパイルする場合:は、テンプレートクラスからジェネリックのstd ::メンバ関数を呼び出すことはできません

#include <functional> 

template <typename functionSignature> 
class Class 
{   
    std::function<functionSignature> func; 
public: 
    Class(const std::function<functionSignature>& arg) : func(arg) {} 
    void callFunc() { func(); } 
}; 

void f(const int i) {} 

int main() 
{ 
    Class<void(const int)> a(std::bind(f, 10)); 
    a.callFunc(); 
    return 0; 
} 

VS 2015のコンパイラは、6行目に次のエラーメッセージを生成:今すぐ

error C2064: term does not evaluate to a function taking 0 arguments. 

、これは、コンパイラがfunctionSignatureというと、関数の署名ではないと思うからだと私は信じています。たとえば、std::function<int()>の代わりにstd::function<int>operator()を呼び出すと、同じエラーが発生します。

std::functionoperator()を呼び出せるように、テンプレート引数が常に関数の署名になることをどうすれば保証できますか?

template <typename F> 
class Class; 

template<typename R, typename... P> 
class Class<R(P...)> { 
public: 
    std::function<R(P...)> func; 
    void callFunc(P... p) { func(p...); } 
}; 

部分特殊あなたは簡単にしたいタイプを定義することができる方法を使用することにより:

+0

に誤った行を変更しますか? – Jts

+0

はい、実際のMCVEが役に立ちます。あなたの 'Class 'のインスタンスを作成するおもちゃ' main'を追加し、 '.callFunc()'を実行し、コンパイルしてMSVCでエラーを生成することを確認します。 – Yakk

答えて

2

あなたのエラーここにある:

Class<void(const int)> a(std::bind(f, 10)); 

機能Class::callFunc()func()を起動する - つまり、引数なし。 std::bind(f, 10)の結果は、引数をとらない関数でもあり、クラステンプレートのテンプレート引数と一致します。 Class<void(const int)>を使用すると、クラステンプレートの使用と初期化の両方に一貫性がありません。

ソリューションは簡単です:あなたがあなたのクラスを呼び出して、どのようにあなたがあなたのクラスを初期化している正確にどのようにあなたのコードを更新してくださいすることができ

Class<void()> a(std::bind(f, 10)); 
+0

さて、OPが元の質問を変更して以来、私の最初の答えはまだ理にかなっていますが、実際にはもっと焦点が当てられています。 – skypjack

+1

@skypjack - あなたが答えを書いた時にはあまり進んでいませんでした。あなたはOPの心を読んで、その後いくつかを読んでいます。あなたの答えは+1です。 –

6

は、私はあなたがそのような何かをしたいと思います。例として
、あなたのようにそれを使用することができます:もちろん

Class<int(double)> c; 

、私はそうfuncを起動することは良いアイデアではありませんが、それはそれを定義するのは非常に簡単です、あなたはあなたのクラスのためのコンストラクタを持っていないことに気づきました適切な関数を引数として渡します。

それは私が機能を呼び出すためにoperator()を使用しました完全な作業例を次に示します。

#include <functional> 

template <typename F> 
class Class; 

template<typename R, typename... P> 
class Class<R(P...)> { 
public: 
    Class(std::function<R(P...)> f): func{f} { } 
    void operator()(P... p) { func(p...); } 
private: 
    std::function<R(P...)> func; 
}; 

void fn() { } 

int main() { 
    std::function<void()> f = fn; 
    Class<void()> c{f}; 
    c(); 
} 
+0

+1これは私がグーグル・グーグルで質問したところで、これは質問のタイトルに基づいていると私は思った。 – AnorZaken

1

は何をしようとするこのですか?

http://ideone.com/fork/IZ0Z1A

functionSignatureが機能していない場合、あなたはクラスを作成するときにはstd ::関数がエラーをスローしますが、あなたは、コンストラクタを追加し、私は推測したい場合がありstatic_assert(std::is_function<functionSignature>::value == true," ");を投げることができました。

#include <functional> 
#include <iostream> 

template <typename functionSignature> 
class Class 
{ 
public: 
    std::function<functionSignature> func; 
    void callFunc() { func(); } 
}; 

void f() 
{ 
    std::cout << "hello" << std::endl; 
} 

int main() 
{ 
    Class<decltype(f)> t {f}; 
    t.callFunc(); 

    return 0; 
} 
関連する問題