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

标签: SFINAE 是否存在某个函数 c++11 完整可运行代码
547人阅读 评论(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在这里还有另外一个妙用,它可以通过逗号表达式连续推断多个函数的返回类型.

运行截图:


查看评论

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

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

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

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

c++ 检查是否存在成员函数

class HasFoo { public : template class SFINAE {}; template static bool test (SFINAE *) ...
  • xcwenn
  • xcwenn
  • 2014-02-26 11:27:40
  • 627

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

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

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

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

C++泛型编程技巧 - 如何判断输入类型是否定义了特定的成员函数

判断一个类型包含了哪些数据或函数成员在提供了类型反射机制的高级语言上大有用处,而C++这种静态语言并未提供直接支持。 需要有类似MFC一样在每个类型里编写组织相关信息的代码才行。 本篇尝试使用一种非侵...
  • chengjian1027
  • chengjian1027
  • 2013-08-24 00:23:42
  • 1176

C++11的模板类型判断——std::is_same和std::decay

C++11的模板类型判断——std::is_same和std::decay问题提出:有一个模板函数,函数在处理int型和double型时需要进行特殊的处理,那么怎么在编译期知道传入的参数的数据类型是i...
  • czyt1988
  • czyt1988
  • 2016-10-14 08:34:20
  • 5573

检查gcc编译器是否C++ 11特性

C++ 11编译器检查Tags: 小工具 简单的检查 #if __cplusplus
  • zstu_cc
  • zstu_cc
  • 2015-12-09 22:25:13
  • 14006

C++ 中SQLITE3 判断表是否存在

在网上搜了好多关于 在C++ 中操作sqlite3 如何判断表是否存在,但是要么集中在  "select count(*) from sqlite_master where type='table' ...
  • wildangel817
  • wildangel817
  • 2015-03-24 16:47:33
  • 2255

c++11学习笔记3——通过更通用的方法实现新特性

1\
  • xiaoxiaoyusheng2012
  • xiaoxiaoyusheng2012
  • 2016-01-22 15:58:03
  • 967
    个人资料
    持之以恒
    等级:
    访问量: 1万+
    积分: 498
    排名: 10万+
    最新评论