如何检测类中是否有特定的成员变量? [英] How to detect whether there is a specific member variable in class?

查看:162
本文介绍了如何检测类中是否有特定的成员变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了创建算法模板函数,我需要知道在类中的x或X(和y或Y)是模板参数。它可能有用的时候使用我的函数为MFC CPoint类或GDI + PointF类或其他一些。他们都使用不同的x。我的解决方案可以缩减为以下代码:

  
template< int& struct TT {typedef int type;};
template< class P> bool Check_x(P p,typename TT< sizeof(&P :: x)> :: type b = 0){return true; }
template< class P> bool Check_x(P p,typename TT
struct P1 {int x; };
struct P2 {float X; };
//它也可以是struct P3 {unknown_type X; };

int main()
{
P1 p1 = {1};
P2 p2 = {1};

Check_x(p1); //必须返回true
Check_x(p2); //必须返回false

return 0;
}

但是它不能在Visual Studio中编译,而是在GNU C ++中编译。使用Visual Studio我可以使用以下模板:

  
模板< class P& bool Check_x(P p,typename TT<&P :: x ==&P :: x> :: type b = 0){return true; }
template< class P> bool Check_x(P p,typename TT<&P :: X ==&P :: X> :: type b = 0){return false; }

但它不能在GNU C ++中编译。是否有通用解决方案?



UPD:这里的结构P1和P2仅是例子。可以是任何具有未知成员的类。



请不要在这里张贴C ++ 11解决方案,因为它们是显而易见的,与问题无关。

解决方案

这一个,它也依赖于 SFINAE表达式。如果名称查找导致模糊,编译器将拒绝模板

  template< typename T& struct HasX {
struct Fallback {int x; }; //引入成员名x
struct Derived:T,Fallback {};

template< typename C,C> struct ChT;

template< typename C> static char(& f(ChT< int Fallback :: *,& C :: x> *))[1];
template< typename C> static char(& f(...))[2];

static bool const value = sizeof(f< Derived>(0))== 2;
};

struct A {int x; };
struct B {int X; };

int main(){
std :: cout< HasX< A> :: value<< std :: endl; // 1
std :: cout<< HasX< B> :: value<< std :: endl; // 0
}

这是基于对某人在usenet上的一个辉煌的想法。 p>

注意:HasX检查任何类型的任何数据或函数成员x。引入成员名称的唯一目的是对成员名称查找可能有歧义 - 成员的类型不重要。


For creating algorithm template function I need to know whether x or X (and y or Y) in class that is template argument. It may by useful when using my function for MFC CPoint class or GDI+ PointF class or some others. All of them use different x in them. My solution could be reduces to the following code:


template<int> struct TT {typedef int type;};
template<class P> bool Check_x(P p, typename TT<sizeof(&P::x)>::type b = 0) { return true; }
template<class P> bool Check_x(P p, typename TT<sizeof(&P::X)>::type b = 0) { return false; }

struct P1 {int x; };
struct P2 {float X; };
// it also could be struct P3 {unknown_type X; };

int main()
{
    P1 p1 = {1};
    P2 p2 = {1};

    Check_x(p1); // must return true
    Check_x(p2); // must return false

    return 0;
}

But it does not compile in Visual Studio, while compiling in the GNU C++. With Visual Studio I could use the following template:


template<class P> bool Check_x(P p, typename TT<&P::x==&P::x>::type b = 0) { return true; }
template<class P> bool Check_x(P p, typename TT<&P::X==&P::X>::type b = 0) { return false; }

But it does not compile in GNU C++. Is there universal solution?

UPD: Structures P1 and P2 here are only for example. There are could be any classes with unknown members.

P.S. Please, do not post C++11 solutions here because they are obvious and not relevant to the question.

解决方案

Another way is this one, which relies on SFINAE for expressions too. If the name lookup results in ambiguity, the compiler will reject the template

template<typename T> struct HasX { 
    struct Fallback { int x; }; // introduce member name "x"
    struct Derived : T, Fallback { };

    template<typename C, C> struct ChT; 

    template<typename C> static char (&f(ChT<int Fallback::*, &C::x>*))[1]; 
    template<typename C> static char (&f(...))[2]; 

    static bool const value = sizeof(f<Derived>(0)) == 2;
}; 

struct A { int x; };
struct B { int X; };

int main() { 
    std::cout << HasX<A>::value << std::endl; // 1
    std::cout << HasX<B>::value << std::endl; // 0
}

It's based on a brilliant idea of someone on usenet.

Note: HasX checks for any data or function member called x, with arbitrary type. The sole purpose of introducing the member name is to have a possible ambiguity for member-name lookup - the type of the member isn't important.

这篇关于如何检测类中是否有特定的成员变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆