2016-08-25 45 views
8

Thông số mẫu mặc định có thể sử dụng "giá trị mặc định" theo cách không bắt đầu từ phải không?thông số mẫu mặc định - không phải là từ phải không? Tại sao nó hoạt động?

Tiêu chí là gì?
Trình biên dịch sẽ diễn giải như thế nào? Ví dụ: Tôi rất ngạc nhiên khi mã này hoạt động.

#include <iostream> 
using namespace std; 

template <bool T=true, class U> //"default" from LEFT-most parameter 
void f(U u){ 
    if(T){ cout<<true;} 
    else cout<<false; 
} 
int main() { 
    auto x = [](){ }; 
    f(x); 
    return 0; 
} 

Xem demo sống ở đây: https://ideone.com/l6d9du

Trả lời

8

Trích đối số mẫu hoạt động tốt ở đây, bởi vì đối với mẫu hàm, các đối số mẫu tiếp theo có thể được suy luận bởi các đối số hàm. Trong trường hợp này, đối số mẫu U có thể được suy ra từ đối số hàm u. Lưu ý rằng đối với mẫu lớp, như bạn mong đợi, tham số mẫu tiếp theo sau một đối số mẫu mặc định sẽ có một đối số mẫu mặc định hoặc là một gói tham số mẫu.

$14.1/11 Template parameters [temp.param]:

Nếu một mẫu tham số của một lớp mẫu, mẫu biến, hoặc alias mẫu có mặc định mẫu đối số, mỗi tiếp theo mẫu tham số trách nhiệm hoặc có một mặc định mẫu đối số được cung cấp hoặc là một gói thông số mẫu. Nếu tham số mẫu của mẫu lớp chính, mẫu biến chính hoặc mẫu bí danh là gói tham số mẫu, nó sẽ là tham số mẫu cuối cùng. Một gói thông số mẫu của mẫu chức năng sẽ không được tuân theo bởi thông số mẫu khác trừ khi tham số mẫu đó có thể là được suy ra từ tham số kiểu danh sách ([dcl.fct]) của hàm mẫu hoặc có đối số mặc định ([temp.deduct]). Mẫu tham số của mẫu hướng dẫn khấu trừ ([temp.deduct.guide]) mà không có đối số mặc định sẽ được khấu trừ từ danh sách loại tham số khấu trừ . [Ví dụ:

template<class T1 = int, class T2> class B; // error 

// U can be neither deduced from the parameter-type-list nor specified 
template<class... T, class... U> void f() { } // error 
template<class... T, class U> void g() { } // error 

- end dụ]

Bạn có thể cố gắng làm cho U undeducible và xem những gì sẽ xảy ra:

template <bool T=true, class U> //"default" from LEFT-most parameter 
void f(){ 
    if(T){ cout<<true;} 
    else cout<<false; 
} 
int main() { 
    f();   // Fail. Can't deduce U. 
    f<true>();  // Fail. Can't deduce U. 
    f<true, int>(); // Fine. T=true, U=int. 
    return 0; 
} 

Lưu ý bạn phải chỉ định tất cả các đối số mẫu một cách rõ ràng để làm cho mã hoạt động, điều này làm cho các đối số mẫu mặc định vô nghĩa. Nếu bạn muốn làm cho các tác phẩm f() hoặc f<true>() hoạt động, bạn cũng cần cung cấp cho U đối số mẫu mặc định (hoặc tạo gói thông số mẫu).

template <bool T=true, class U=int> 
void f(){ 
    if(T){ cout<<true;} 
    else cout<<false; 
} 
int main() { 
    f();    // Fine. T=true, U=int 
    f<false>();  // Fine. T=false, U=int 
    f<false, char>(); // Fine. T=false, U=char 
    return 0; 
} 
4

Bạn có thể cung cấp một mặc định cho bất kỳ tham số.

Nếu bạn muốn sử dụng làm mặc định, bạn không thể xác định rõ ràng thông số ở bên phải thông số mặc định. Tuy nhiên, trong ví dụ của bạn, U đang được suy luận từ loại đối số cho hàm và T đang được đặt mặc định.

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