如何检测类中是否存在特定的成员变量?

How to detect whether there is a specific member variable in class?(如何检测类中是否存在特定的成员变量?)
本文介绍了如何检测类中是否存在特定的成员变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了创建算法模板函数,我需要知道作为模板参数的类中是 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.

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

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Rising edge interrupt triggering multiple times on STM32 Nucleo(在STM32 Nucleo上多次触发上升沿中断)
How to use va_list correctly in a sequence of wrapper functions calls?(如何在一系列包装函数调用中正确使用 va_list?)
OpenGL Perspective Projection Clipping Polygon with Vertex Outside Frustum = Wrong texture mapping?(OpenGL透视投影裁剪多边形,顶点在视锥外=错误的纹理映射?)
How does one properly deserialize a byte array back into an object in C++?(如何正确地将字节数组反序列化回 C++ 中的对象?)
What free tiniest flash file system could you advice for embedded system?(您可以为嵌入式系统推荐什么免费的最小闪存文件系统?)
Volatile member variables vs. volatile object?(易失性成员变量与易失性对象?)