将PARENT类成员的名称作为模板参数传递

时间:2016-06-08 09:24:38

标签: c++ templates

如何将父'成员的姓名传递给模板参数?

很难解释,所以我会改为显示短代码。

示例

此代码的A源自Mother。我想将母亲的名字传递给B的模板。

它没有编译。我已经标记了发生错误的行。

class Mother{
public:
    int motherField=3;   
};

class A: public Mother { 
public:
    int childField=4; 
}; //note: not virtual inherit

template <class T, int T::*a>
class B{ }; 

int main() { 
    B<A,&A::motherField> b;
    //^ could not convert template argument '&Mother::motherField' to 'int A::*'
}

如果我改变了&#34; motherField&#34; to&#34; childField&#34;,它可以编译。

看起来编译器认为Mother :: motherField与A :: motherField

非常不同

问题

我想传递父母的成员,无论如何都要让它编译?

动机

B是一个特殊的hashMap。我们将其命名为AMap。

AMap要求密钥(A)必须为其提供一个字段(可能是int,&#34; motherField&#34; /&#34; childField&#34;在示例中),以缓存一些索引。

AMap<A,&A::dedicatedField1> b1;  //I omit the value part for simplicity.
AMap<A,&A::dedicatedField2> b2;
A a1;
b1.cache(a1); //b1 read&write a1.dedicatedField1
b2.cache(a1); //b2 read&write a1.dedicatedField2

这会带来很多性能优势。

b1.get(a1);//b1 just read a1.dedicatedField1, then it know where a1 is stored

为方便起见,我在A之母中提供了一个默认的dedicatedField,所以有时我可以将Mother :: defaultDedicatedField插入AMap(B)。

因此A.h不必包含专用字段,因此代码更清晰。

1 个答案:

答案 0 :(得分:1)

指向成员的指针具有他们实际上是其成员的类的类型。因此,即使您编写&A::motherField,类型也不是int A::*,而是int Mother::*。编译错误来自类型不匹配。

您必须将指向成员的指针强制转换为您想要的类型:

B<A, static_cast<int A::*>(&A::motherField)> b;

但这对gcc或clang都不起作用(不明白为什么),所以最好在B中提供第三个默认类型参数。如果需要,您可以使用最后一种类型来指定派生类 - 例如:

template <class C, int C::*a, class T=C> class B { }; 

B<Mother, &A::motherField, A> b;