2016-03-27 23 views
5

Do sau đơn giản structvariadic mẫu nhà xây dựng ưu tiên

template <typename T> 
struct A 
{ 
    A(T a) {} 

    template <typename ... Ts> 
    A(T a, Ts ... more) {} 
}; 

int main() 
{ 
    A<int> a(1); 
} 

đảm bảo rằng A(T a) sẽ được gọi thay vì mẫu constructor variadic là gì, và tại sao?

Trả lời

6

Phần trong tiêu chuẩn mà bạn đang tìm kiếm là §14.8.2.4

Nếu A đã được chuyển đổi từ một gói thông số chức năng và P không phải là một gói thông số, loại trừ thất bại. Nếu không, bằng cách sử dụng các kiểu kết quả P và A, việc khấu trừ được thực hiện như mô tả trong 14.8.2.5. Nếu P là gói tham số hàm, loại A của mỗi loại tham số còn lại của mẫu đối số là so với loại P của bộ khai báo-id của gói tham số hàm. Mỗi so sánh sẽ trừ ra đối số mẫu cho các vị trí tiếp theo trong các gói thông số mẫu được mở rộng theo gói tham số chức năng . Nếu khấu trừ thành công cho một loại nhất định, loại từ mẫu đối số được coi là ít nhất là chuyên biệt như loại từ mẫu tham số.

[Ví dụ:

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 

- end dụ]

+1

14.8.2.4 là về so sánh hai mẫu chức năng để xem đó là chuyên biệt hơn. Nhưng một trong những hàm ứng viên trong ví dụ này không phải là một mẫu chức năng nào cả. – aschepler

+0

@aschepler Bạn đang nói rằng trình biên dịch không cần phải đạt được điều này, bởi vì có một hàm không phải mẫu, đó là một kết hợp hoàn hảo có nghĩa là nó thậm chí không cần phải bắt đầu độ phân giải mẫu. Tôi đồng ý. Sẽ có một phần khác bao gồm điều này. –

2

Cùng lý do f(const int&) là một trận đấu tốt hơn so với f(const T&) khi T có thể được suy luận như int: A(int) là một hàm phi mẫu và A(int, Ts...) với Ts... suy luận như danh sách rỗng là một hàm template đặc biệt.

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