2016-04-18 19 views
20

Tôi bị lúng túng: khi nâng cấp lên GCC 6 (RC1) một số mã mẫu sử dụng std::common_type hoạt động trước khi không thành công. Tôi đã thử trên tiếng kêu, và điều đó cũng thất bại ... vì vậy tôi phải làm điều gì đó sai trái!std :: common_type với tham chiếu đến type_info

Mã số tiền:

#include <type_traits> 
#include <typeinfo> 

using namespace std; 

// common_type of two const type_info& is ok (compiles ok) 
common_type<const type_info&, const type_info&>::type func1(); 

// common_type of three type_info& is bad...(fails to compile) 
common_type<const type_info&, const type_info&, const type_info&>::type func2(); 

// common_type of two const int& is ok 
common_type<const int&, const int&>::type func3(); 

// common_type of three const int& is ok too! 
common_type<const int&, const int&, const int&>::type func4(); 

Thứ hai common_type với ba thông số của loại std::type_info const & thất bại trong việc biên dịch. clang cryptically gợi ý tôi sử dụng một hai đối số std::common_type, nhưng điều này là trong một bản mở rộng mẫu mà tôi không thể kiểm soát đầu vào!

Điều này có vẻ rất kỳ lạ: tại sao trường hợp const type_info& với 3 lỗi nhưng không phải bất kỳ loại dường như tương đương nào khác không thành công?

Xem ở đây: https://godbolt.org/g/Ob4y0x

+3

'common_type' hiện phân rã và kết quả là những điều" vui nhộn ". –

+0

Một số tài liệu tham khảo twitter chỉ cho tôi thực tế là 'std :: common_type' trả về' std :: decay' của Ts ... điều này gây phiền toái cho trường hợp sử dụng của tôi nhưng giải thích các lỗi ở trên. –

+0

@MattG: Bạn luôn có thể thay thế 'common_type_t 'theo' common_type_t ...> ', tuy nhiên, nó không nên gây phiền toái. –

Trả lời

15

Thứ nhất, common_type_t<T1, T2> là (khoảng) std::decay_t<decltype(true? std::declval<T1>() : std::declval<T2>())>. Nó phân rã loại - loại bỏ tính giới thiệu, loại bỏ cv-qualification cấp cao nhất, và thực hiện chuyển đổi mảng-thành-con trỏ và hàm-to-pointer.

Vì vậy, common_type<const type_info&, const type_info&>::typetype_info. Trong khi tuyên bố của func1 dường như hoạt động, bạn sẽ gặp phải các vấn đề nghiêm trọng khi viết định nghĩa của nó.

common_type_t<T1, T2, T3>common_type_t<common_type_t<T1, T2>, T3>, vì vậy common_type<const type_info&, const type_info&, const type_info&>::typecommon_type<type_info, const type_info&>::type.

Kết quả đó trong biểu thức thứ ba danh mục hỗn hợp, theo quy tắc trong [expr.cond] sẽ cố gắng thực hiện tạm thời type_info trong toán hạng đã chọn - không hoạt động vì hàm tạo bản sao của type_info bị xóa.

Trong triển khai thân thiện với SFINAE, kết quả là common_type<const type_info&, const type_info&, const type_info&> không có thành viên type. Nếu bạn sử dụng triển khai không thân thiện với SFINAE, thay vào đó, bạn sẽ gặp phải một lỗi nghiêm trọng.

+0

Cảm ơn, điều đó chắc chắn sẽ trả lời câu hỏi. Bất kỳ ý tưởng tại sao điều này thay đổi cho C++ 14 mặc dù? Có vẻ như tôi thiếu điều gì đó nếu mã của tôi đã hoạt động trước đây nhưng không phải bây giờ :) –

+5

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2141 –

+2

@MattG^that (Tóm lại, để 'common_type_t ' không phải là 'int &&'). –

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