2015-11-01 54 views
2
template <typename IN,typename OUT,bool isVector> 
OUT foo(IN x){ 
    if (isVector){ 
     return x[0];  
    } else { 
     return x; 
    } 
} 

在詢問this question之後,我錯誤地認爲上述代碼可以編譯爲例如。如何修復此模板:

foo<double,double,false>; 

以及

foo<std::vector<double>,double,true>; 

然而,即使如果支行從未得到執行的一個,檢查的正確性,因此上面沒有編譯。我該如何解決它?

上面的代碼是一個簡化,但我不知道如何解決它,因爲函數模板不能有偏特...

回答

4

可以「提取」你要專注於模板參數,使他們一些結構的模板參數,並寫有剩餘的模板參數靜態成員函數的函數:

template<bool IsVector = true> 
struct Bar { 
    template<typename In> 
    static auto foo(In input) { 
     return input[0]; 
    } 
}; 
template<> 
struct Bar<false> { 
    template<typename In> 
    static auto foo(In input) { 
     return input; 
    } 
}; 

Live example.

顯然,這導致在調用位置變化,這喲ü可以「捕獲」使用被調用相應功能的免費功能:

template<typename In, bool IsVector> 
auto real_foo(In input) { 
    return Bar<IsVector>::foo(input); 
} 

結構(Bar),然後通常把一個「幫手」命名空間內。


另一種可能性是使用標籤和重載決議:

template<typename In> 
auto foo(In input, std::true_type) { 
    return input[0]; 
} 
template<typename In> 
auto foo(In input, std::false_type) { 
    return input; 
} 
template<bool IsVector, typename In> 
auto foo(In input) { 
    using tag = typename conditional<IsVector, true_type, false_type>::type; 
    return foo(input, tag{}); 
} 

Live example.

這使用std::conditionalstd::true_typestd::false_type不同類型允許重載決議找到合適的foo功能。

+0

看起來不錯,我會嘗試 – user463035818

+0

我更喜歡第一個解決方案,第二個看起來像C++ 11,我不能使用不幸的。然而,從模板類「A」調用函數時,我無法運行它,並且我傳遞的模板參數(代碼中的「In」)是「A」的模板參數。任何想法,爲什麼這可能是?我將嘗試將其製作成MCVE ... – user463035818

+0

不編譯的MCVE:http://ideone.com/NQwfyA – user463035818