2017-06-30 3 views
17

ich versuchte SFINAE Werke zu verstehen, wie und ich experimentierte mit diesem CodeWarum void_t funktioniert nicht in SFINAE aber enable_if tut

#include <type_traits> 

struct One { 
    using x = int; 
}; 
struct Two { 
    using y = int; 
}; 

template <typename T, std::void_t<typename T::x>* = nullptr> 
void func() {} 
template <typename T, std::void_t<typename T::y>* = nullptr> 
void func() {} 

/*template <typename T, std::enable_if_t<std::is_same_v<typename T::x, typename T::x>>* = nullptr> 
void func() {} 
template <typename T, std::enable_if_t<std::is_same_v<typename T::y, typename T::y>>* = nullptr> 
void func() {} */ 



int main() { 
    func<One>(); 
    func<Two>(); 
} 

Die kommentierten Code funktioniert, aber der erste nicht. Der Compiler gibt mir Fehler, die sagen, dass es eine Neudefinition gibt und dass der Abzug des Template-Arguments fehlgeschlagen ist. Könnte jemand erklären, warum das passiert? Die beiden void_t s sollten unabhängig sein, oder? Da eine Zeile nach x und die andere nach y sucht. Wie kann ich reparieren?

+1

Beachten Sie, dass das funktioniert mit dem [ 'make_void' Trick] (https://wandbox.org/ permlink/iiNGJAqXnq35HIJP). –

Antwort

13

Dies scheint zu CWG issue #1980(Guthaben zu T.C. für die Korrektur mich).

Als Abhilfe können Sie void_t wie definieren:

template<typename... Ts> struct make_void { typedef void type;}; 
template<typename... Ts> using void_t = typename make_void<Ts...>::type; 

(from cppreference)

live example on wandbox

+1

Whoa dieses Problem ist noch nicht in den neuen Installationen von C++ 17 auf gcc behoben worden? –

+0

Offenbar nicht. :(Ich sehe einen Unterschied auf g ++ 7.1.0 zwischen dem Standard 'void_t' und dem obigen' void_t'. – aschepler

+0

@Whoami: Ich bin auch überrascht. Wenn meine Antwort in der Tat richtig ist, ist das ziemlich traurig –

Verwandte Themen