2017-05-07 82 views
2

我無法爲類模板特化中的模板化方法制作專門的模板。在模板化類中的模板化方法中重載std :: function參數

比方說,我有以下代碼:

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

如果我想專門功能barmyClass<void>我會做這種方式:

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

} 

但是,當我試圖專注foo以同樣的方式,我得到一個編譯器錯誤,指出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 ::功能''不是的std ::函數 Maliafo

+0

我做了,錯誤保持不變。 – waran

+1

最後一部分看起來像函數模板的部分特化(並且缺少模板參數),這是禁止的。 'foo'專業化應該看起來像'template <> template <> bool myClass :: foo < void >(std :: function g)'。或者你應該把它寫在'myClass'模板特化中,因爲這個模板類專用化需要新的'foo'模板函數,你不能像在專用模板中那樣專門從基本模板中專門化'foo'。 – VTT

回答

3

不完全專業化...您可以使用SFINAE(std::enable_if)來激活的foo()你的版本時Tvoid和激活foo()另一個版本時Tvoid

下面是一個完整的工作示例

#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