2017-06-23 18 views
6

Tôi đã phát hiện ra rằng các đoạn mã sau:mẫu template đặc tả từng phần chỉ làm việc với -std = C++ 1Z với g ++

#include <iostream> 
#include <vector> 

template <typename T> 
struct X : std::false_type {}; 

template <template <typename> class Y, typename U> 
struct X<Y<U>> : std::true_type {}; 

int main() { 
    if (X<int>()) 
    std::cout << "wrong\n"; 

    if (X<std::vector<double>>()) 
    std::cout << "correct\n"; 

    return 0; 
} 

Chỉ in correct khi biên soạn với g++-7 với -std=c++1z. Các phiên bản khác của g++, clang++ hoặc các cờ std khác không đúng.

Đây có phải là lỗi của việc triển khai hiện tại và mã này không được in bất kỳ thứ gì hoặc có thay đổi gì trong C++ 17 khiến mã này hoạt động như tôi mong đợi không?

+0

Thực tế thú vị: nếu bạn thực hiện 'Y' lấy một số đối số variadic, nó sẽ in' correct' cho clang trên '-std = C++ 1z' ​​và không có gì cho gcc trên' -std = C++ 17 ':) – Rakete1111

+0

Vẫn in' đúng' bằng 'g ++ - 7' ở đây .. – Svalorzen

Trả lời

9

Đây là kết quả của việc áp dụng các P0522 trong C++ 17, có động lực là, từ ví dụ:

template <template <int> class> void FI(); 
template <template <auto> class> void FA(); 
template <auto> struct SA { /* ... */ }; 
template <int> struct SI { /* ... */ }; 
FI<SA>(); // OK; error before this paper 
FA<SI>(); // error 

template <template <typename> class> void FD(); 
template <typename, typename = int> struct SD { /* ... */ }; 
FD<SD>(); // OK; error before this paper (CWG 150) 

Trước đây, các từ ngữ trong [temp.arg.template] các thông số mẫu mẫu bắt buộc để khớp chính xác bằng hiện vật. Vì vậy, đưa ra:

template <template <class > class P> class X; 

template <class T> class A; 
template <class T, class U=T> class B; 
template <class... > class C; 

X<A> rõ ràng là không sao, nhưng X<B> là vô hình thành vì B có hai tham số mẫu (! Bất kể nếu ai mặc định) và X<C> là vô hình thành vì P hy vọng một mẫu tham số và C mất một gói (ngay cả khi bạn có thể tạo thành một C chỉ với một thông số duy nhất!)

Từ ngữ mới sẽ làm mất ý tưởng của một kết quả phù hợp với ý nghĩa đó - nếu tham số mẫu mẫu ít nhất là chuyên biệt tranh luận. Điều đó làm cho X<B>X<C> đều hoạt động.

Do đó, trong C++ 17, X<std::vector<double>> nên chọn chuyên môn. Nhưng trước khi C++ 17, nó nên chọn chính. gcc đang làm đúng.

+0

xem lướt qua bài báo đó có vẻ như đó là về các tham số mẫu không kiểu, không phải là trường hợp ở đây. Bạn có thể cụ thể hơn/dumbed xuống về cách này là có liên quan trong trường hợp này? – xaxxon

+0

@xaxxon Glance lâu hơn? Nó không phải về các tham số mẫu không kiểu nào cả - đó là về các mẫu khuôn mẫu. Ví dụ 'FD ()' chính xác là những gì OP đang làm. – Barry

+0

cảm ơn bạn, tôi hiểu ngay bây giờ. – xaxxon

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