2015-06-13 17 views
2

此代碼編譯並運行正常鏗鏘,但給人的gcc編譯錯誤:這個模板函數是否能正確地匹配一個具有多個基數的類?

no matching function for call to ‘unpack(tag1, A3&)’

因此,它是合法的C++?

#include <type_traits>               
#include <utility>                
#include <cassert>                                  

template <class Tag, class Value>             
class Pack                  
{                     
public:                   
    Pack(const Value& value) : _value(value) {}          
    Value value() const { return _value; }           
private:                   
    Value _value;                 
};                                     

template<class Tag, class Value>             
decltype(auto) unpack(Tag, Pack<Tag, Value>& pack) {        
    return pack.value();               
}                     

struct tag1 {};                 
struct tag2 {};                 

struct A3 : Pack<tag1, int>, Pack<tag2, double> {         
    A3(int x, double y) : Pack<tag1, int>(x), Pack<tag2, double>(y) {}    
};                    

int main() {                  
    A3 a3(1, 2);                 
    assert(unpack(tag1(), a3) == 1);            
    assert(unpack(tag2(), a3) == 2);            
}  
+0

在此上下文中的「有效」意味着兩件事情 - 合成正確或良好的設計。你是指哪一個? –

+0

句法正確 – rnickb

+1

@RSahu:我不同意。在這種情況下,「有效」只能意味着句法上的正確。 – ruakh

回答

2

Tag在每個功能參數(TagPack<Tag, Value> &)的推導環境中。模板參數推導獨立執行,結果必須匹配。當試圖從A3中推導出Pack<Tag, Value>時,可能有兩種可能的扣除,所以類型扣除失敗。

最簡單的修復方法可能是擺脫標記函數參數,而只是用明確的模板參數調用unpack - unpack<tag1>(a3)不比unpack(tag1(), a3)更詳細。如果您仍然喜歡原始語法,可以編寫一個轉發器:

template<class Tag, class SomePack> 
decltype(auto) unpack(Tag, SomePack& pack) { return unpack<Tag>(SomePack); } 
+0

與nondeduced版本仍然給與gcc相同的錯誤(4.9.2) – rnickb

+0

@rnickb你是對的,我搞砸了我的測試代碼 –

+0

與nondeduced法律(只是一個海灣合作委員會的錯誤)的版本? – rnickb

0

這不僅是多重繼承的問題。這也是模板即時的問題。

表達unpack(tag1(), a3)匹配到一個函數的與簽名unpack(tag1, Pack<tag1, A3> &)一個呼叫和return pack.value()是曖昧當組是Pack<tag1, A3>類型。

這意味着decltype(auto)的編譯器(假設C++ 14)將會失敗。

+0

爲什麼它會解包(tag1,包&)?與clang的第一個斷言匹配解壓(tag1,包&),我沒有看到任何歧義,推斷decltype(自動)在該上下文中的返回類型 – rnickb

+0

這是因爲你在考慮如果模板已經實例化。含糊之處在於實例化模板 - 這是一個獨立的過程,必須在您的邏輯應用之前解決。 – Peter

相關問題