2016-03-02 13 views
14

Rozważmy następujący kod:Dlaczego idiom wykrywania void_t <> nie działa z 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; 
} 

g ++ wersji 5 i później (a -std = C++ 14 znaczników, oczywiście), kod wyjścia

1 0 

jak należy. Z g ++ w wersji 4.9 (i -std = C++ 14 Flag), jednak wyprowadza

1 1 

Obaj twierdzą, że stosując tę ​​samą normę językową, więc co za problem tutaj?

+2

Czy używasz wersji 4.9.0 lub wyższej? Widziałem kilka błędów w wersji 4.9.0, które zostały naprawione, jeśli przejdziesz do 4.9.2. – NathanOliver

+0

4.9.3 być dokładnym –

+0

Cóż, to było wszystko, co mogłem wnieść. jeśli to sprawia, że ​​czujesz się lepiej, to działa również na klang. – NathanOliver

Odpowiedz

16

Jest to spowodowane wynikiem CWG Issue 1558 i jest obecnie uważane za błąd w gcc (w szczególności 64395 - obecnie rozwiązany). Ideą tej kwestii jest to, że ponieważ w rzeczywistości nie używać parametry szablonu tutaj.

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

nie ma awarii podstawienie niezależnie od tego, jakiego rodzaju lub wyrażenia próby przekazania w

Na szczęście, nie ma łatwe obejście, które nie wymaga aktualizacji kompilatora. Możemy przepisać void_t rzeczywiście wykorzystać swój pakiet parametru, tym samym powodując awarię podstawiania:

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

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

To będzie dokonać przykład postąpić właściwie we wszystkich wersjach GCC próbowałem.

Powiązane problemy