2013-06-27 153 views
2

想象一個類(在VS2010,沒有可變參數模板這裏對不起)條件編譯

template <class Arg> 
class FunctionWrapper 
{ 
public: 
     void Invoke(Arg arg){_fn(arg)}; 
private: 
     std::function<void(Arg)> _fn; 
} 

然後我就可以做如

FunctionWrapper <int> foo; foo.Invoke(4); 

而且這個編譯好。但這並不:

FunctionWrapper <void> foo; foo.Invoke(); 

現在,我可以解決這個使用模板特殊化。但我也想知道是否有一個辦法可以解決這個問題的另一種方式....

template <class Arg> 
class FunctionWrapper 
{ 
public: 
     void Invoke(void){_fn()};     // } overloaded 
     void Invoke(Arg arg){_fn(arg)};    // } 
private: 
     std::function<void(Arg)> _fn; 
} 

即超載調用,然後在條件編譯答覆,這樣,如果我實例 FunctionWrapper<void>, 調用的版本與參數永遠不會被編譯。我確定我在Modern C++設計中讀到了如何做到這一點,但我不記得細節.....

+0

我認爲這是使用專業化的完美場景,即使你問的問題可以做,有什麼好處? –

+0

答:我對如何做到這一點感興趣,因爲我認爲這可能是可能的,而且我想知道。 B,它可以節省我爲虛空專業定義第二個,大體上相同的類定義。 –

回答

0

如果您試圖通過這種方式實現仿函數,那麼會出現一些明顯的缺陷在設計中;我認爲,你似乎在評論中明確表示,代碼只是一個用來說明你的情況的例子。

這裏有幾個解決方案的問題:

template<class T> 
struct Trait{ 
    typedef T type; 
    typedef T mock_type; 
}; 
template<> 
struct Trait<void>{ 
    typedef void type; 
    typedef int mock_type; 
}; 

template <class Arg> 
class FunctionWrapper 
{ 
public: 
     void Invoke(void){_fn();} 
     void Invoke(typename Trait<Arg>::mock_type arg){_fn(arg);} 
     boost::function<void(typename Trait<Arg>::type)> _fn; 
private: 
}; 

template <class Arg> 
class FunctionWrapper2 
{ 
public: 
    FunctionWrapper2(const boost::function<void(Arg)> arg) : Invoke(arg){} 
    const boost::function<void(Arg)> Invoke; 
}; 

int main(int argc, _TCHAR* argv[]) 
{ 

    FunctionWrapper<int> cobi; 
    cobi._fn = &countOnBits<int>; 
    cobi.Invoke(5); 

    FunctionWrapper<void> cobv; 
    cobv._fn = &func; 
    cobv.Invoke(); 

    FunctionWrapper2<int> cobi2(&countOnBits<int>); 
    cobi2.Invoke(5); 

    FunctionWrapper2<void> cobv2(&func); 
    cobv2.Invoke(); 
    //[...] 
} 

當然,我不是說我寫的是好的代碼,至於這個問題它只能用於提供工作結構的例子。

你的嘗試的問題是,雖然函數void Invoke(Arg arg){_ fn(arg)};實際上沒有在你實例化FunctionWrapper的時候被編譯(並且不要試圖用參數調用Invoke函數),它會被語法檢查;當然Invoke(void arg)不是你的編譯器會接受的東西!

這是我在stackoverflow上的第一個答案,我希望我的一切都正確;如果沒有,請給我一些反饋,不要太難過我:)