什么是SFINAE不能正常工作与下面的has_member函数? [英] What does SFINAE not work correctly with following has_member function?

查看:257
本文介绍了什么是SFINAE不能正常工作与下面的has_member函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试 Walter Brown的TMP讲座的示例,我想让他的 has_member 实现工作。



但是实现似乎错误地返回true,这导致我相信有一些细节的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< FooWithType有类型成员吗?<<
(has_type_member< FooWithType>()?YES:NO)< \\\
;

std :: cout<< FooNoType有类型成员吗?<<
(has_type_member< FooNoType>()?YES:NO)< \\\
;

return 1;
}

输出是:

  FooWithType有类型成员吗? YES 
FooNoType有类型成员吗? YES

我在Ubuntu上的gcc 4.8.2。

voider 类模板:

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

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


唉,我们在使用
时遇到了实现分歧(Clang vs. GCC) 。我们(继续)推测这是因为CWG问题1558:
对别名模板特殊化中未使用的参数的处理未由
当前字眼14.5.7 [temp.alias]指定。



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.

解决方案

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]."

这篇关于什么是SFINAE不能正常工作与下面的has_member函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆