2017-05-07 7 views
2

クラステンプレートの特殊化でテンプレートメソッドの特殊テンプレートを作成する際に問題があります。テンプレートクラスのテンプレートメソッドのstd :: functionパラメータのオーバーロード

のは、私は次のコードを持っているとしましょう:私はfooを専門にしようとしたとき

template<> void myClass<void>::bar() { 

} 

しかし:私はmyClass<void>のための機能barを専門としたい場合、私はそれをこのように行うだろう

#include <functional> 

template<typename T> 
class myClass { 
public: 
    T bar() { 
     return T(); 
    } 

    template<typename P> 
    bool foo(std::function<P(T)> g) { 
     g(bar()); 
     return true; 
    } 
}; 

同じ方法で、私はerror: invalid parameter type ‘void’と言って、fooの元の定義を指してコンパイラエラーを取得します。

template<> 
template<typename P> 
bool myClass<void>::foo(std::function<P(void)> g) { 
    bar(); 
    g(); 
    return true; 
} 

私は何を間違えているのですか?

+0

フル実施例であるあなたの代わりに 'のstd ::関数を'使用しようとしましたか? – Maliafo

+0

私は、エラーは同じままだった。 – waran

+1

最後の部分は、禁止されている関数テンプレートの部分的な特殊化(およびテンプレート引数がない)のように見えます。 'foo'の特殊化は' template <> template <> bool myClassのようになります。 :: foo < void >(std :: function g) 'あるいは、テンプレートクラスの特殊化には新しい 'foo'テンプレート関数が必要なので、' myClass'テンプレートの専門化の中に書かなければなりません。特殊テンプレートのように 'foo'を基本テンプレートから特殊化することはできません。 – VTT

答えて

3

ない正確に専門...あなたはTvoidないときfoo()のバージョンをアクティブにし、Tvoidときfoo()の別のバージョンをアクティブにするSFINAE(std::enable_if)を使用することができます。

次は

#include <iostream> 
#include <functional> 

template <typename T> 
class myClass 
{ 
    public: 
     T bar() 
     { return {}; } 

     template <typename P, typename U = T> 
     typename std::enable_if<false == std::is_same<U, void>::value, 
       bool>::type foo (std::function<P(U)> const & g) 
     { g(bar()); return true; } 

     template <typename P, typename U = T> 
     typename std::enable_if<true == std::is_same<U, void>::value, 
       bool>::type foo (std::function<P()> const & g) 
     { bar(); g(); return false; } 
}; 

template<> 
void myClass<void>::bar() 
{ } 

int main() 
{ 
    myClass<int> mci; 
    myClass<void> mcv; 

    std::function<long(int)> fli { [](int i){ return long(i); } }; 
    std::function<short()> fsv { [](){ return 0; } }; 

    std::cout << mci.foo(fli) << std::endl; // print 1 
    std::cout << mcv.foo(fsv) << std::endl; // print 0 
} 
+0

ありがとう、それは私の問題を解決しました。 :) – waran

+1

それは問題を解決しましたが、質問に答えませんでした。 – Walter

関連する問題