What does SFINAE not work correctly with following has_member function?

强颜欢笑 提交于 2019-12-19 00:45:34

问题


I'm trying out examples from Walter Brown's TMP talk and I'm trying to get his has_member implementation working.

However the implementation seems to falsely return true which leads me to believe there is some detail of SFINAE that I am not understanding.

#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;                                                                                                                 
}      

Output is:

Does FooWithType have type member? YES
Does FooNoType have type member? YES

I am on gcc 4.8.2 on Ubuntu.


回答1:


The problem is that gcc 4.8.2 (and prior to gcc 5.0) does not regard unused arguments in alias templates as suitable for SFINAE. The workaround is to forward to a voider class template:

template <class ... T> struct voider { using type = void; };
template <class ... T>
using void_t = typename voider<T...>::type;

From http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3911.pdf section 2.3:

Alas, we have encountered implementation divergence (Clang vs. GCC) while working with the above very simple definition. We (continue to) conjecture that this is because of CWG issue 1558: “The treatment of unused arguments in an alias template specialization is not specified by the current wording of 14.5.7 [temp.alias].”



来源:https://stackoverflow.com/questions/30781523/what-does-sfinae-not-work-correctly-with-following-has-member-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!