2014-07-12 14 views
6

clang 3.4 chấp nhận mã sau; trong khi vC++ tháng 11 năm 2013 CTP bác bỏ nó với một lỗi:Tại sao mã được chấp nhận bởi clang nhưng bị từ chối bởi vC++?

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); 
} 

nào biên dịch là đúng theo tiêu chuẩn C++ 14?

Cập nhật: Các thông báo lỗi đầy đủ:

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. 
+4

Side lưu ý : '__GetFirst__' là tên dành riêng. –

+0

Bạn có thể gửi thông báo lỗi đầy đủ không? –

+0

không biết đó là chính xác, nhưng dễ dàng sửa chữa là có variadic mất 3 + params – sp2danny

Trả lời

8

Clang (và GCC) 's hành vi là đúng. Bạn có thể đọc §14.8.2.4 [temp.deduct.partial] của tiêu chuẩn cho cách đặt hàng một phần cho các chức năng mẫu được thực hiện, nhưng các ví dụ được đưa ra trong p8 của phân lớp trực tiếp bao gồm tình trạng này:

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 
+2

+1. Ngoài ra, hãy thêm mã định danh '[bracked subsection]' cho mệnh đề phụ đó để dễ tìm hơn trong các phiên bản khác nhau của tiêu chuẩn. (Các mệnh đề cụ thể #s di chuyển xung quanh nhưng những số nhận dạng đó được sửa) –

+2

@BillyONeal Tôi muốn cãi nhau về các mã định danh đó đang được sửa ('basic.lookup.koenig'->' basic.lookup.argdep' :)) nhưng được lấy điểm. –

+0

T.C. lol - tốt, tương đối cố định ở mức nào –

Các vấn đề liên quan