C++ SFINAE在以下has_成员功能中无法正常工作的原因是什么?

C++ SFINAE在以下has_成员功能中无法正常工作的原因是什么?,c++,templates,c++11,template-specialization,sfinae,C++,Templates,C++11,Template Specialization,Sfinae,我正在尝试来自的示例,我正在尝试让他的成员实现工作正常 然而,这个实现似乎错误地返回了真值,这让我相信SFINAE的某些细节我并不理解 #include <iostream> #include <type_traits> template <class ...> using void_t = void; template <class, class = void> struct has_type_member: std::false_type

我正在尝试来自的示例,我正在尝试让他的
成员
实现工作正常

然而,这个实现似乎错误地返回了真值,这让我相信SFINAE的某些细节我并不理解

#include <iostream>
#include <type_traits>

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

template <class, class = void>
struct has_type_member: std::false_type {};

template <class T> 
struct has_type_member<T, void_t<typename T::type> >: std::true_type {};

struct FooWithType
{
    typedef int type;
};

struct FooNoType 
{
};

int main()
{
    std::cout << "Does FooWithType have type member? " << 
        (has_type_member<FooWithType>() ? "YES" : "NO") << "\n";

    std::cout << "Does FooNoType have type member? " << 
        (has_type_member<FooNoType>() ? "YES" : "NO") << "\n";

    return 1;                                                                                                                 
}      

我在Ubuntu上使用GCC4.8.2。

问题是GCC4.8.2(以及GCC5.0之前)并不认为别名模板中未使用的参数适合SFINAE。解决方法是转发到
作废者
类模板:

template <class ... T> struct voider { using type = void; };
template <class ... T>
using void_t = typename voider<T...>::type;
template struct voider{using type=void;};
模板
使用void\u t=typename voider::type;
第2.3节:

遗憾的是,我们在使用 上面的定义非常简单。我们(继续)推测这是因为CWG 1558号问题: “别名模板专用化中未使用参数的处理方式不是由 14.5.7[临时别名]的当前措辞。”


您确定您的void\t实现正常吗?我记得它不是这样实施的。甚至对于格式错误的模板,它也可能返回void?请参阅,以及相关/重复:进一步重复:对于g++5,它可以按预期工作。@dyp right,未使用的默认参数。我花了一段时间才找到布朗论文中的措辞。对于较新版本的GCC来说仍然如此吗?@KABoissonneault GCC 5.0及以上版本不需要解决方法。
template <class ... T> struct voider { using type = void; };
template <class ... T>
using void_t = typename voider<T...>::type;