2016-05-13 15 views
6

Xét đoạn mã sau:phần Template chuyên môn hóa và icc

template <class T, class U, class V> 
struct Foo { }; 

template <class T, class U> 
struct Foo<T, U, std::integral_constant<int, U::value>> { 
    static void print() 
    { 
    std::cerr << "instantiated"; 
    } 
}; 

template <class U> 
struct Foo<double, U, std::integral_constant<int, U::value>> { 
    static void print() 
    { 
    std::cerr << "instantiated special"; 
    } 
}; 

struct Bar { 
    static const int value = 0; 
}; 

int main(int argc, char ** argv) 
{ 
    using Baz = Foo<double, Bar, std::integral_constant<int, 0>>; 
    Baz::print(); 

    return 0; 
} 

Khi tôi biên dịch này với icc 16.0.1, tôi nhận được thông báo sau:

main.cpp(38): error: more than one partial specialization matches the template argument list of class "Foo<double, Bar, std::integral_constant<int, 0>>" 
      "Foo<T, U, std::integral_constant<int, U::value>>" 
      "Foo<double, U, std::integral_constant<int, U::value>>" 
    Baz::print(); 

Với vang 3.7.1 và gcc 5.3.0 này biên dịch (và "instantiated đặc biệt" được in). Đây có phải là lỗi trong icc hay mã của tôi không chính xác? Đối với tôi, có vẻ rõ ràng rằng chuyên môn hóa thứ hai nghiêm túc hơn chuyên môn thứ nhất; nó giống với đầu tiên khác với thực tế là nó khóa thông số mẫu đầu tiên.

Chỉnh sửa: Tôi nên thêm: nếu đây là lỗi trong icc, có cách giải quyết tốt không?

+0

Có vẻ như một lỗi trong icc với tôi. – Cameron

+0

Bạn có thể kiểm tra xem các đề xuất trong [comments below] (https://stackoverflow.com/questions/37216212/partial-template-specialization-and-icc#comment61972971_37216503) có khắc phục được sự cố trên ICC không? Không phải là một sửa chữa hoàn chỉnh cho vấn đề của bạn, tất nhiên, chỉ là một bước tiến trong cuộc điều tra. – bogdan

+0

Trong mã thực tế, số nguyên đến từ một thành viên lồng nhau của U, điều này lần lượt cho vấn đề clang, do đó, đồng nghiệp của tôi chuyển từ loại không để loại tham số mẫu. –

Trả lời

4

Có, đây là lỗi trong ICC.


Cả hai chuyên ngành một phần phù hợp với thực hiện của bạn, vì vậy đi vào các quy tắc mẫu đặt phần trên hai chức năng tổng hợp:

template <class T, class U> void f(Foo<T, U, std::integral_constant<int, U::value>); 
template <class U>   void f(Foo<double, U, std::integral_constant<int, U::value>); 

Các quy tắc đặt hàng một phần liên quan đến việc tổng hợp loại mới cho mỗi mẫu đối số và cố gắng làm khấu trừ với mỗi quá tải với phần còn lại. Trước tiên, chúng tôi cố gắng suy ra U chống lại Foo<_U1, _U2, std::integral_constant<int, _U2::value>>. Điều này không thành công, vì _U1 không khớp với double. Vì vậy, quá tải đầu tiên không phải là ít nhất là chuyên ngành hơn so với thứ hai. Tiếp theo, chúng tôi cố gắng suy ra TU chống lại Foo<double, _U3, std::integral_constant<int, _U3::value>>. Điều này thành công với T=doubleU=_U3. Vì vậy, quá tải thứ hai ít nhất là chuyên môn đầu tiên.

Do đó, quá tải thứ hai chuyên biệt hơn lần đầu tiên. Có một phần riêng biệt nhất từng phần một phần, là một trong đó nên được instantiated (và là do gcc và clang). ICC không làm như vậy là một lỗi.

+0

Các bối cảnh trật tự và không suy luận tại nơi làm việc một lần nữa ... Thay thế 'U :: giá trị' bằng một suy luận' int I' rất có thể sẽ làm cho mọi thứ hoạt động như mong đợi. Nó trông giống như front-end EDG (rất có thể được sử dụng bởi ICC ở đây) đồng ý với MSVC và làm cho không quá tải ít nhất là chuyên ngành như khác vì bối cảnh không suy luận. Thật đáng tiếc, tôi đã thử nghiệm một EDG không phải MSVC-quirks trong chế độ '--strict' của nó và nó vẫn làm điều tương tự. Đó là 2 trên 2 như trình biên dịch đi. Thật tuyệt. – bogdan

+0

@bogdan Tại sao điều đó làm cho khấu trừ không thành công? – Barry

+0

Tôi đồng ý rằng việc khấu trừ không thành công trong bước thứ hai trong phần giải thích của bạn sẽ không có ý nghĩa gì. Tôi đã chỉ ra rằng bối cảnh không suy luận có nhiều khả năng là nguyên nhân của vấn đề (và tôi rất ngạc nhiên trước hành vi của EDG). Tôi sẽ yêu cầu OP kiểm tra nếu thay đổi 'U :: value' thành' 0' (hoặc như đã đề xuất ở trên) khắc phục sự cố trên ICC. – bogdan

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