SFINAE 使用 decltype 检查静态成员

sfinae check for static member using decltype

本文关键字:静态成员 检查 decltype 使用 SFINAE      更新时间:2023-10-16

我编写了以下代码来尝试检测类型是否具有静态成员变量。 不幸的是,它总是返回变量不存在。

有人可以告诉我哪里出错了吗? 我正在使用 g++ 4.7.1。

#include <iostream>
#include <utility>
#include <type_traits>
using namespace std;
template <class T>                                                  
class has_is_baz                                                          
{                                                                   
    template<class U, 
             typename std::enable_if<std::is_same<bool, decltype(U::is_baz)>::value>::type...>                    
        static std::true_type check(int);                           
    template <class>                                                
        static std::false_type check(...);                          
public:                                                             
    static constexpr bool value = decltype(check<T>(0))::value;     
};
struct foo { };
struct bar 
{ 
    static constexpr bool is_baz = true;
};
int main()
{
    cout << has_is_baz<foo>::value << 'n';
    cout << has_is_baz<bar>::value << 'n';
}

主要问题是:

std::is_same<bool, decltype(bar::is_baz)>::value == false

然后你的SFINAE总是失败。我已经重写了has_is_baz特征,它现在可以工作了:

#include <iostream>
#include <utility>
#include <type_traits>
using namespace std;
template <class T>                                                  
class has_is_baz                                                          
{       
    template<class U, class = typename std::enable_if<!std::is_member_pointer<decltype(&U::is_baz)>::value>::type>
        static std::true_type check(int);
    template <class>
        static std::false_type check(...);
public:
    static constexpr bool value = decltype(check<T>(0))::value;
};
struct foo { };
struct bar 
{ 
    static constexpr bool is_baz = true;
};
struct not_static {
    bool is_baz;
};
int main()
{
    cout << has_is_baz<foo>::value << 'n';
    cout << has_is_baz<bar>::value << 'n';
    cout << has_is_baz<not_static>::value << 'n';
}

编辑:我已经修复了类型特征。如@litb所示,它正在检测静态成员和非静态成员。

代码中的问题是constexpr对象是隐式const的,这意味着您对相同类型的测试应该是:

std::is_same<const bool, decltype(U::is_baz)>::value

这在 §7.1.5 [dcl.constexpr]/9 的标准中有所规定

对象声明

中使用的 constexpr 说明符将对象声明为 const。