Why is the code accepted by clang but rejected by vC ++?

clang 3.4 accepts the following code; while vC ++ NOV 2013 CTP rejects it with an error:

error C2668: 'AreEqual' : ambiguous call to overloaded function 
 template<class headT, class... tailTypes> constexpr headT&& __GetFirst__(headT&& value, tailTypes&&...) { return static_cast<headT&&>(value); }; template<class T> constexpr bool AreEqual(const T& a, const T& b) { return a == b; } template<class headT, class... tailTypes> constexpr bool AreEqual(const headT& head_value, const tailTypes&... tail_values) { return AreEqual(head_value, __GetFirst__(tail_values...)) && AreEqual(tail_values...); } int main() { AreEqual(1, 1, 2, 1); } 

Which compiler is correct according to the C ++ 14 standard?

Update: full error message:

 error C2668: 'AreEqual' : ambiguous call to overloaded function 1> d:\projects\ktl\test\main.cpp(20): could be 'bool AreEqual<headT,int>(const headT &,const int &)' 1> with 1> [ 1> headT=int 1> ] 1> d:\projects\ktl\test\main.cpp(8): or 'bool AreEqual<headT>(const T &,const T &)' 1> with 1> [ 1> headT=int 1> , T=int 1> ] 1> while trying to match the argument list '(const int, const int)' 1> 1>Build FAILED. 
+6
source share
1 answer

Clang (and GCC) behavior is correct. You can read ยง14.8.2.4 of the [temp.deduct.partial] standard on how partial ordering is performed for function templates, but the example given in p8 of this subclause directly covers this situation:

 template<class... Args> void f(Args... args); // #1 template<class T1, class... Args> void f(T1 a1, Args... args); // #2 template<class T1, class T2> void f(T1 a1, T2 a2); // #3 f(); // calls #1 f(1, 2, 3); // calls #2 f(1, 2); // calls #3; non-variadic template #3 is more // specialized than the variadic templates #1 and #2 
+8
source

Source: https://habr.com/ru/post/972114/


All Articles