2017-09-19 18 views
18

Hãy xem xét một ví dụ đơn giản:Are loại placeholders của phi kiểu mẫu thông số hoán đổi cho nhau trong trường hợp mẫu template tham số

int x; 

template <template <auto> class TT> 
struct Foo { 
    void foo() { 
     TT<(x)> tt; 
     static_cast<void>(tt); 
    } 
}; 

template <decltype(auto)> 
struct Bar { }; 


int main() { 
    Foo<Bar> foobar; 
    foobar.foo(); 
} 

[clang] dường như để đối phó với các ý tưởng của decltype(auto) giữ chỗ mặc dù việc sử dụng các auto trong mẫu tham số mẫu tuyên bố mà không có vấn đề gì.

[gcc] mặt khác - không phải là rất tốt:

prog.cc:6:13: error: the value of 'x' is not usable in a constant expression


Như thường - mà hành vi dự kiến ​​theo tiêu chuẩn? Hoặc có thể mọi thứ đều có thể và đoạn mã không đúng định dạng (lần này tôi cho là không nhưng không thể loại trừ nó một cách dứt khoát)?

PS. Xin lỗi vì đã vi phạm một trong các trình biên dịch một lần nữa;)

+2

Tôi không thấy cách chỉ định '(x)' cho tham số mẫu, trong đó 'x' là một biến, hợp lệ đối với bất kỳ loại mẫu nào. Lần trước tôi đã kiểm tra thông số mẫu chỉ có thể là một loại hoặc một hằng số. –

+5

@SamVarshavchik cho 'decltype (tự động)' nó được giải quyết cho một tham chiếu một biến miễn là biến có liên kết tất nhiên (lần cuối tôi kiểm tra điều này thực sự hợp lệ;)) –

+2

Vâng, cái này xứng đáng là một upvote, sau đó . –

Trả lời

7

Câu trả lời ban đầu ở đây có Foo<Bar> không đúng định dạng, tôi thực sự nghĩ rằng nó được định dạng tốt. Nhưng cuối cùng, lỗi dựa trên clang.


Tôi thực sự nghĩ rằng thậm chí Foo<Bar> là không đúng định dạng. Các quy định mới, sau P0522 là rằng:

A template-argument matches a template template-parameterP when P is at least as specialized as the template-argumentA

nơi:

A template template-parameterP is at least as specialized as a template template-argumentA if, given the following rewrite to two function templates, the function template corresponding to P is at least as specialized as the function template corresponding to A according to the partial ordering rules for function templates ([temp.func.order]). Given an invented class template X with the template parameter list of A (including default arguments):

  • Each of the two function templates has the same template parameters, respectively, as P or A .
  • Each function template has a single function parameter whose type is a specialization of X with template arguments corresponding to the template parameters from the respective function template where, for each template parameter PP in the template parameter list of the function template, a corresponding template argument AA is formed. If PP declares a parameter pack, then AA is the pack expansion PP... ([temp.variadic]); otherwise, AA is the id-expressionPP .

If the rewrite produces an invalid type, then P is not at least as specialized as A .

Có nghĩa là để xác minh nếu Foo<Bar> chính nó là okay, chúng tôi tổng hợp:

template <decltype(auto) I> struct X; 

template <auto I>   void __f(X<I>); // P 
template <decltype(auto) I> void __f(X<I>); // A 

Tất cả các loại đây là hợp lệ (vì vậy câu lệnh cuối cùng không áp dụng). Bây giờ, thông thường khi chúng ta thực hiện một phần thứ tự nó trong bối cảnh của độ phân giải quá tải hoặc chọn một chuyên môn mẫu lớp, trong trường hợp đó chúng ta đang tìm kiếm mẫu chức năng "more specialized", trong đó Fmore specialized thanG nếu ít nhất là F như GG không ít nhất là chuyên ngành như F.

Nhưng trong bối cảnh này, chúng tôi không quan tâm đến điều nào là chuyên biệt hơn. Chúng tôi chỉ cần P ít nhất phải là A. Tất cả điều đó có nghĩa là khấu trừ phải thành công từ A đến P. Vì vậy, nếu chúng tôi tổng hợp một số loại duy nhất U với một số giá trị V, chúng tôi có thể suy ra X<I> từ X<V> không? Vâng. Do đó, P ít nhất là chuyên ngành là A, do đó, đối số mẫu Bar khớp với thông số mẫu TT.


Bây giờ, hãy vượt qua điểm đó, tôi sẽ nói lỗi này là lỗi. Mẫu mẫu tham sốtemplate <auto>, đó là những gì chúng tôi nên sử dụng để xác thực biểu thức. Với thông số mẫu không phải là loại auto, chúng tôi sẽ cố gắng sử dụng x làm giá trị - nhưng x không phải là biểu thức hằng số hợp lệ, do đó điều này sẽ không thành công.clang dường như đang sử dụng trực tiếp template <decltype(auto) > - điều mà tôi không chắc chắn là hợp lệ.

Điều đó nói rằng, tôi không chắc chắn trường hợp này thậm chí đã được xem xét - Tôi không thấy bất kỳ từ ngữ nào theo cách này hay cách khác và nó đáng để gây ra vấn đề.

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