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

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

问题描述

为了创建算法模板函数,我需要知道作为模板参数的类中是 x 还是 X(以及 y 或 Y).在将我的函数用于 MFC CPoint 类或 GDI+ PointF 类或其他一些类时,它可能很有用.他们都使用不同的 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;
}

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

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; }

但它不能在 GNU C++ 中编译.有通用的解决方案吗?

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

UPD:此处的结构 P1 和 P2 仅用作示例.可能有任何具有未知成员的类.

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

附言请不要在此处发布 C++11 解决方案,因为它们很明显且与问题无关.

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

推荐答案

另一种方式是这个,它依赖于 SFINAE 表达式.如果名称查找导致歧义,编译器将拒绝模板

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
}

它基于 usenet 上某人的绝妙想法.

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

注意:HasX 检查任何名为 x 的数据或函数成员,具有任意类型.引入成员名称的唯一目的是使成员名称查找可能存在歧义——成员的类型并不重要.

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天全站免登陆