2017-10-22 15 views
14

Đây là cách std::thread constructor tuyên bố (sử dụng Visual Studio 2015):mục đích của std :: thread constructor third template parameter là gì?

template<class _Fn, 
class... _Args, 
class = typename enable_if< 
    !is_same<typename decay<_Fn>::type, thread>::value>::type> 
explicit thread(_Fn&& _Fx, _Args&&... _Ax) 

Không có câu hỏi liên quan đến _Fn_Args, tuy nhiên, thứ ba class = ... confuses me hoàn toàn. Nó làm gì, nó hoạt động như thế nào và nó là gì?

+3

Dường như, nó vô hiệu hóa hàm tạo này trong trường hợp '_Fn' là kiểu' std :: thread'; Tôi nghi ngờ nó là để tránh các lỗi cuộc gọi mơ hồ với các nhà xây dựng bản sao. –

Trả lời

16

Đó là ví dụ về điều kiện quá tải sử dụng SFINAE.

Quá tải này không được xem xét để giải quyết quá tải nếu đối số đầu tiên thuộc loại std::thread.

Lưu ý rằng nguồn gốc của tiêu đề chuẩn C++ không có ý định đọc. Nó cũng là không có ý định bắt chước. Trình biên dịch của trình biên dịch C++ có thể thực hiện nhiều thứ trong việc triển khai tiêu đề std của chúng mà bạn không thể và không nên làm bên ngoài các tiêu đề đó. Ít nhất trong số đó là bắt đầu một biến với một _ theo sau là một chữ cái viết hoa (bị cấm trong mã người dùng).

Kiểm tra loại đối số mặc định nếu _Fn là một số std::thread, tham chiếu đến cùng hoặc tham chiếu đến cùng một sửa đổi cv.

typename enable_if< 
!is_same<typename decay<_Fn>::type, thread>::value>::type> 

decay<_Fn>::type dải tham chiếu và chứng chỉ cv. Nó cũng chuyển đổi các tham chiếu đến hàm thành các hàm con trỏ đến hàm và tham chiếu đến các mảng thành phần tử con trỏ đến đầu tiên, nhưng điều đó không quan trọng ở đây.

Giả sử _Fnthread&. Tôi sẽ evalulate:

typename enable_if< 
!is_same<typename decay<thread&>::type, thread>::value>::type> 
typename enable_if< 
!is_same<thread, thread>::value>::type> 
typename enable_if< 
!true>::type> 
typename enable_if< 
false>::type> 
/* substitution failure occurs */> 

enable_if<B>::type chỉ tồn tại nếu Btrue; khi _Fn là một chuỗi, nó là sai, do đó có một sự thất bại thay thế trong quá trình phân giải quá tải.

SFINAE nghĩa là lỗi thay thế không phải là lỗi, và thay vì trình biên dịch phàn nàn, nó chỉ đơn giản loại bỏ tình trạng quá tải này khỏi xem xét. Và thay vào đó, hàm tạo thread(thread const&) (mà tôi tin là =delete ed).

5

Thông số mẫu chưa đặt tên thứ ba có giá trị mặc định, được sử dụng để đáp ứng yêu cầu sau đây của constructor of std::thread qua SFINAE, để tránh sự xáo trộn khi hàm tạo di chuyển được gọi.

Nhà xây dựng này không tham gia vào quá trình phân giải quá tải nếu std::decay_t<Function> cùng loại với std::thread.