2016-03-02 15 views
14

Xét đoạn mã sau:Tại sao thành phần phát hiện void_t <> không hoạt động với gcc-4.9?

#include <iostream> 
#include <type_traits> 

struct Test { Test& operator++(); }; 
struct NoIncrement { }; 

template <typename...> using void_t = void; 

template <class, class=void_t<>> 
struct has_pre_increment_member : std::false_type { }; 

template <class T> 
struct has_pre_increment_member<T, void_t<decltype(++std::declval<T&>())>> 
    : public std::true_type { }; 

int main() { 
    std::cout << has_pre_increment_member<Test>::value << " "; 
    std::cout << has_pre_increment_member<NoIncrement>::value << std::endl; 
} 

Với g ++ phiên bản 5 và sau đó (và -std = C++ 14 lá cờ, tất nhiên), mã này đầu ra

1 0 

như nó phải. Với g ++ phiên bản 4.9 (và cờ -std = C++ 14), tuy nhiên, kết quả đầu ra là

1 1 

Cả hai đều yêu cầu sử dụng cùng một ngôn ngữ chuẩn, vậy vấn đề ở đây là gì?

+2

Bạn có sử dụng 4.9.0 hoặc cao hơn không? Tôi đã thấy một số lỗi trong 4.9.0 đã được sửa chữa nếu bạn đi đến 4.9.2. – NathanOliver

+0

4.9.3 chính xác –

+0

Đó là tất cả những gì tôi có thể đóng góp. nếu nó làm cho bạn rơi bất kỳ tốt hơn nó hoạt động trên clang quá. – NathanOliver

Trả lời

16

Điều này xuất phát từ kết quả của CWG Issue 1558 và hiện được coi là lỗi trong gcc (cụ thể là 64395 - hiện đã được sửa). Ý tưởng đằng sau vấn đề này là vì bạn không thực sự sử dụng các thông số mẫu tại đây:.

template <typename...> using void_t = void; 

không có thất bại thay bất kể những gì loại hoặc biểu thức bạn cố gắng để vượt qua trong

Rất may, có một dễ dàng giải quyết mà không liên quan đến việc nâng cấp trình biên dịch của bạn. Chúng ta có thể viết lại void_t thực sự sử dụng gói thông số của nó, do đó gây ra sự thất bại thay:

namespace void_details { 
    template <class... > 
    struct make_void { using type = void; }; 
} 

template <class... T> using void_t = typename void_details ::make_void<T...>::type; 

Điều đó sẽ làm cho ví dụ bạn làm điều đúng trên tất cả các phiên bản gcc tôi đã cố gắng.

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