关闭

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

标签: SFINAE是否存在某个函数c++11完整可运行代码
86人阅读 评论(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网站的观点或立场
    个人资料
    • 访问:5511次
    • 积分:388
    • 等级:
    • 排名:千里之外
    • 原创:30篇
    • 转载:3篇
    • 译文:0篇
    • 评论:1条
    最新评论