2017-06-18 29 views
13

Xét đoạn mã sau:Tại sao trình biên dịch không thể suy ra tham số mẫu khi được sử dụng với toán tử chuyển đổi?

#include <utility> 

template<typename T> 
struct wrapper { 
    T value; 
}; 

struct foo { 
    operator wrapper<int>() { 
     return{10}; 
    } 
}; 


int main() { 
    foo f; 
    wrapper w = f; // error 
    std::pair p = std::make_pair(1, 0); // ok 
} 

gcc 7.1.1 thất bại trong việc biên dịch tại dòng rõ rệt trên:

main.cpp: In function 'int main()': 
main.cpp:17:17: error: class template argument deduction failed: 
    wrapper w = f; // error 
       ^
main.cpp:17:17: error: no matching function for call to 'wrapper(foo&)' 
main.cpp:4:8: note: candidate: template<class T> wrapper(wrapper<T>)-> wrapper<T> 
struct wrapper { 
     ^~~~~~~ 
main.cpp:4:8: note: template argument deduction/substitution failed: 
main.cpp:17:17: note: 'foo' is not derived from 'wrapper<T>' 
    wrapper w = f; // error 
       ^

f là mui trần để wrapper<int>, vì vậy tôi hy vọng điều đó xảy ra. Từ đó trình biên dịch có thể suy ra rằng Tint. Nhưng nó không thể.

Trình biên dịch có thể suy ra chính xác thông số mẫu của std::pair một cách chính xác, vì vậy tôi tự hỏi tại sao đây không phải là trường hợp với wrapper.

Bất kỳ ý tưởng nào?

+0

IMO sẽ rất khó hiểu nếu khấu trừ mẫu lớp học được xem xét trong các toán tử chuyển đổi. Nếu cần, bạn nên sử dụng hướng dẫn khấu trừ rõ ràng. – cpplearner

+0

Liên quan: https://stackoverflow.com/q/43019240/1896169 – Justin

+0

trình bao bọc cấu trúc toán tử 'này là gì ()'? nó có khai báo 'toán tử wrapper' hoặc' toán tử() '? – cat

Trả lời

11

Để khấu trừ đối số mẫu lớp, "tập quá tải" được tạo thành như được mô tả trong [over.match.class.deduct/1]. Đó là những điều sau đây:

gồm

Một tập hợp các chức năng và chức năng các mẫu được hình thành:
(1.1) - Đối với mỗi phương thức dựng của lớp mẫu chính được chỉ định bởi mẫu tên tuổi, nếu mẫu được định nghĩa, một mẫu chức năng với các thuộc tính sau:
(1.1.1) - Tham số mẫu là thông số mẫu của mẫu lớp theo sau là tham số mẫu (bao gồm đối số mẫu mặc định) của hàm tạo, nếu có.
(1.1.2) - Các kiểu tham số chức năng là các tham số của hàm tạo.
(1.1.3) - Kiểu trả về là mẫu lớp học chuyên môn được chỉ định bởi tên mẫu và đối số mẫu tương ứng với thông số mẫu lấy từ mẫu lớp.

(1.2) - Nếu mẫu lớp C không được xác định hoặc không khai báo bất kỳ hàm tạo nào, mẫu hàm bổ sung bắt nguồn từ ở trên từ hàm tạo giả thuyết C().

(1.3) - Một mẫu hàm bổ sung có nguồn gốc như trên từ một nhà xây dựng giả thuyết C (C) được gọi là ứng viên khấu trừ bản sao.

(1,4) - Đối với mỗi trích-dẫn, một chức năng hoặc chức năng mẫu với các thuộc tính sau:
(1.4.1) - Các thông số mẫu, nếu có, và chức năng các thông số là của các deduction- hướng dẫn.
(1.4.2) - Kiểu trả về là mẫu-id đơn giản của hướng dẫn khấu trừ.

Như bạn có thể thấy, "hàm" khớp trong 1,1 chỉ cố gắng đối sánh các loại đối số với các loại thông số mẫu chính xác. Nó không đưa chuyển đổi vào tài khoản (giống như hầu hết các hành vi liên quan đến khấu trừ mẫu khác).

Lý do hoạt động cho std::pair là do mục 1.3 và "ứng viên khấu trừ bản sao" được xác định.

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