关闭

C++11 SFINEA规则_判断类是否存在某个成员函数

标签: SFINAE是否存在某个函数c++11完整可运行代码
274人阅读 评论(0) 收藏 举报
分类:

在C++模板中,SFINEA规则是指”Substitution failure is not an error“(匹配失败不是错误)。具体来说,就是当重载的模板参数展开时,如果展开导致一些类型不匹配,编译器并不报错。

我们可以使用这个规则来判断类是否存在某个成员函数,请看下面的实例:

#include<iostream>
#include<utility>
#include<type_traits>

template<typename T>
struct has_member_foo
{
private:
    template<typename U>
        static auto Check(int) -> decltype( std::declval<U>().foo(), std::true_type() );
    template<typename U>
        static std::false_type Check(...);
public:
    enum { value = std::is_same<decltype(Check<T>(0)),std::true_type>::value  };
};

struct myStruct
{
    void foo() { std::cout << "hello" << std::endl;  }
};

struct another
{
    void test() { std::cout << "test" << std::endl;  }
};

int main()
{
    if( has_member_foo<myStruct>::value )
    	std::cout << "myStruct has foo funciton"  << std::endl;
    else
        std::cout << "myStruct does't have foo funciton"  << std::endl;

    if( has_member_foo<another>::value )
    	std::cout << "another has foo function"  << std::endl;
    else
	std::cout << "another does't have foo function"  << std::endl;
    return 0;
}
这个has_member_foo的作用就是检查类型是否存在非静态成员foo函数

具体的实现思路是这样的:定义两个重载函数Check,由于模板实例化的过程中会优先选择匹配程度最高的重载函数,在模板实例化的过程中检查类型是否存在foo函数,如果存在则返回std::true_type,否则返回std::false_type. 巧妙的利用了C++的SFINAE特性.

template<typename U> static auto Check(int) -> decltype(std::declval<U>().foo(), std::true_type());

最关键的一句代码: 配合decltype来获取函数foo的返回类型,如果获取成功则表明存在foo函数,否则就会替换失败,而选择默认的Check函数(不会报错,SFINAE)。decltype在这里还有另外一个妙用,它可以通过逗号表达式连续推断多个函数的返回类型.

运行截图:


1
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

C++怎么判断一个类存在指定的函数名的函数

C++怎么获得一个类存在指定的函数名的函数怎么在编译期获得一个类是否存在指定函数名的函数?#define HAS_MEMBER(member)\ templatestruct has_memb...
  • zhx6044
  • zhx6044
  • 2015-08-05 12:28
  • 3137

[c++11] 判断某类是否有某个原型及名称的成员函数

 #include "stdafx.h" #include #include template struct IndexedTWrap {  typedef T type...
  • superzmy
  • superzmy
  • 2014-07-18 08:47
  • 1017

[c++11] 判断 类内是否有指定名字的 字段/成员函数/静态函数/typedef

 #include "stdafx.h" #include #include template::value >::type> short existFirst(...
  • superzmy
  • superzmy
  • 2014-07-18 10:37
  • 1215

C++11模板:如何判断类中是否有指定名称的成员变量?

如何判断类中有指定的成员函数,网上可以找到不少的文章,比如下面这两篇就写得很详细了 《C++11之美》 《C++模板,判断是否存在成员函数,实现差异化操作 》 我现在关心的是如何判断一个类中...
  • 10km
  • 10km
  • 2016-04-10 17:11
  • 2254

[c++] 判断类下是否有某个指定类型及名称的字段

 #include "stdafx.h" #include #include template struct IndexedTWrap {  typedef T ty...
  • superzmy
  • superzmy
  • 2014-07-18 09:46
  • 988

(SFINAE)C++检查成员函数是否存在

C++使用SFINAE检查成员函数是否存在
  • zjq2008wd
  • zjq2008wd
  • 2017-02-28 10:20
  • 514

C++11模板:如何判断类中是否有指定名称的成员变量?

如何判断类中有指定的成员函数,网上可以找到不少的文章,比如下面这两篇就写得很详细了 《C++11之美》 《C++模板,判断是否存在成员函数,实现差异化操作 》 我现在关心的是如何判断一个类中...
  • 10km
  • 10km
  • 2016-04-10 17:11
  • 2254

C++怎么判断一个类存在指定的函数名的函数

C++怎么获得一个类存在指定的函数名的函数怎么在编译期获得一个类是否存在指定函数名的函数?#define HAS_MEMBER(member)\ templatestruct has_memb...
  • zhx6044
  • zhx6044
  • 2015-08-05 12:28
  • 3137

redis有序集合中是否存在某个成员

redis命令使用参考网页:http://redis.cn/commands.html有序集合中,redis没有命令直接判断有序集合中是否存在某个成员,自行通过代码实现,示例代码如下:#include...
  • tennysonsky
  • tennysonsky
  • 2017-04-30 10:56
  • 1804

C++11特性--新的类功能--特殊的成员函数(移动构造函数,移动赋值运算符),默认方法和禁用方法(default,delete),委托构造函数,管理虚方法(override,final)

1.新的类功能   (1)特殊的成员函数        *在原有4个特殊成员函数(默认构造函数,复制构造函数,复制赋值运算符和析构函数)的基础上,C++11新增了两个:移动构造函数,移动赋值运算符。这...
  • piniheaven
  • piniheaven
  • 2013-07-25 07:06
  • 1716
    个人资料
    • 访问:10121次
    • 积分:441
    • 等级:
    • 排名:千里之外
    • 原创:32篇
    • 转载:3篇
    • 译文:0篇
    • 评论:6条
    最新评论