2014-01-18 74 views
5

我不擅長C++,所以這可能是新手的錯誤。我正在嘗試製作一個異構鏈接列表類型,其中每個節點的類型和其他列表的類型在每個節點中都已知。Clang&GCC誤導模板參數

這裏是一個SSSCE:

#include <utility> 

template<typename T, typename... Rest> 
struct hnode { 
    T data; 
    hnode<Rest...>* next; 
}; 

template<typename T> 
struct hnode<T> { 
    T data; 
    std::nullptr_t next; 
}; 

template<typename T, typename... Rest> 
hnode<T> hcons(T&& val, std::nullptr_t) { 
    return { std::forward<T>(val), nullptr }; 
} 

template<typename T, typename... Rest> 
hnode<T, Rest...> hcons(T&& val, hnode<Rest...>& next) { 
    return { std::forward<T>(val), &next }; 
} 

int main() { 
    hnode<int> three = hcons(1, nullptr); 
    auto two = hcons("hi", three); 
} 

然而,GCC給了我這個錯誤代碼:

test.cc: In function ‘int main()’: 
test.cc:28:29: error: no matching function for call to ‘hcons(const char [3], hnode<int>&)’ 
auto two = hcons("hi", three); 
          ^
test.cc:28:29: note: candidates are: 
test.cc:17:10: note: template<class T, class ... Rest> hnode<T> hcons(T&&, std::nullptr_t) 
hnode<T> hcons(T&& val, std::nullptr_t) { 
     ^
test.cc:17:10: note: template argument deduction/substitution failed: 
test.cc:28:29: note: cannot convert ‘three’ (type ‘hnode<int>’) to type ‘std::nullptr_t’ 
auto two = hcons("hi", three); 
          ^
test.cc:22:19: note: hnode<T, Rest ...> hcons(T&&, hnode<Rest ...>&) [with T = const char (&)[3]; Rest = {int, Rest}] 
hnode<T, Rest...> hcons(T&& val, hnode<Rest...>& next) { 
       ^
test.cc:22:19: note: no known conversion for argument 2 from ‘hnode<int>’ to ‘hnode<int, Rest>&’ 

鏘足以讓我來解決它是稍微更簡潔,但仍然沒有幫助:

test.cc:28:12: error: no matching function for call to 'hcons' 
auto two = hcons("hi", three); 
      ^~~~~ 
test.cc:17:10: note: candidate function [with T = char const (&)[3], Rest = <>] not viable: no known conversion from 'hnode<int>' to 'std::nullptr_t' (aka 'nullptr_t') for 2nd argument 
hnode<T> hcons(T&& val, std::nullptr_t) { 
     ^
test.cc:22:19: note: candidate template ignored: substitution failure [with T = char const (&)[3], Rest = <>]: too few template arguments for class template 'hnode' 
hnode<T, Rest...> hcons(T&& val, hnode<Rest...>& next) { 
       ^   ~~~~~ 
1 error generated. 

,因爲它是演繹Rest是似乎不可思議當它應該清楚地是<int>,它說它是<int>上面的線no known conversion from 'hnode<int>' to 'std::nullptr_t'。我犯了什麼錯誤?

+0

'hcons'的第一個重載不需要參數包。 – 0x499602D2

+0

@ 0x499602D2哦,挺對的。我刪除它,但得到相同的錯誤。顯然有不可扣除的可變參數模板參數不是問題,所以這實際上不是一個錯誤。 – user3175411

+0

我不會從'hcons'的第一個重載中刪除無用的'typename ... Rest',因爲它會弄亂錯誤信息。它是無害的,但不是錯誤的原因。 – user3175411

回答

1

不知道爲什麼,但作爲HNODE至少有一個模板參數,這個工程:

#include <utility> 

template<typename T, typename... Rest> 
struct hnode { 
    T data; 
    hnode<Rest...>* next; 
}; 

template<typename T> 
struct hnode<T> { 
    T data; 
    std::nullptr_t next; 
}; 

template<typename T> 
hnode<T> hcons(T&& val, std::nullptr_t) { 
    return { std::forward<T>(val), nullptr }; 
} 

template<typename T, typename S, typename... Rest> 
    hnode<T, S, Rest...> hcons(T&& val, hnode<S, Rest...>& next) { 
    return { std::forward<T>(val), &next }; 
} 

int main() { 
    hnode<int> three = hcons(1, nullptr); 
    auto two = hcons("hi", three); 
    auto one = hcons(5.14f, two); 
} 

在你的版本,一旦未能找到最佳匹配,這是正常的編譯器列表中的所有候選人。真正的問題仍然存在,爲什麼鏗鏘是在模板參數包扣除錯誤...

Visual Studio 2013成功的兩個版本(有和沒有S),仍然失敗的const char(*)[3 ]我用一個int代替測試...

Clang或Visual,誰是對的,我不知道,但在這裏填寫一個bug報告可能是一個好主意。