加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

这个SFINAE C语法如何工作?

发布时间:2020-12-16 09:48:41 所属栏目:百科 来源:网络整理
导读:我刚刚开始涉足SFINAE并且我无法理解以各种形式出现的最常用示例背后的语法,但其目的是检查特定类型是否包含给定成员.这个特别的是从 Wikipedia: template typename T struct has_typedef_foobar { typedef char yes[1]; typedef char no[2]; template type
我刚刚开始涉足SFINAE并且我无法理解以各种形式出现的最常用示例背后的语法,但其目的是检查特定类型是否包含给定成员.这个特别的是从 Wikipedia:

template <typename T> struct has_typedef_foobar 
{
    typedef char yes[1];
    typedef char no[2];

    template <typename C> static yes& test(typename C::foobar*);
    template <typename> static no& test(...);

    static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};

有几件事我不明白:

>返回“是”的test()重载的参数类型是什么?它是指针吗?为什么typename关键字用作参数的一部分?我已经看到它也用于测试一个类是否具有给定类型的成员,而不仅仅是一个typedef,并且语法保持不变.
>有时候我见过使用test(int C :: *)的例子.这更奇怪,不知道我们引用的是哪个C成员.如果它是一个真实的函数与一个实体,实例化为一个真实的类型,并且参数被命名,它会指向什么,你将如何使用它?

template <typename T> func(int T::*arg)
{
    *arg = 1;
}

struct Foo
{
    int x;
} foo;

func<Foo>(&foo::x); // something like this?
func(&foo::x); // or maybe even like this?

>是模板< typename>如果没有在第二次过载中使用,则不允许使用符号?那它甚至是模板功能呢?
>奖励:是否可以一次检查是否存在多个成员?

解决方法

其中大多数问题与SFINAE无关:

>当依赖名称应被视为类型时,它需要以typename开头.由于C是test()的模板参数,显然C :: foobar是一个依赖名称.尽管函数声明需要在每个参数前面加一个类型,但该语言需要使用typename将依赖名称C :: foobar转换为一个类型.有了它,typename C :: foobar只是一个类型并将类型构造函数*应用于它,产生相应的指针类型.> int C :: *是一个未命名的指向int类型数据成员的指针.>总是可以省略未使用的名称.这适用于函数参数以及模板参数,即是,如果不使用模板,则可以省略模板之后的名称.大多数情况下,它以某种形式使用,在这种情况下,显然是必需的.>我认为你可以编写一个测试,测试多个方面的存在,但我不会这样做:SFINAE是不可读的.我宁愿将不同的属性测试与普通逻辑运算符结合使用.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读