具有Pointer to Member模板参数的隐含类型?

时间:2012-08-08 03:54:14

标签: c++ templates template-meta-programming pointer-to-member

我在模板中使用指向成员类型的指针,目前我还有这样的事情:

template <typename Base, typename Type, Type Base::* Var>
struct Member
{
    //Stuff goes here.
};

但是必须定义Base,Type和Var,似乎有点多余,因为Base和Type隐含在Var的类型中。

有没有办法做到这一点,这样,当使用/调用Member结构时,它只需要使用单指针到成员的参数?在理论上,就像这样:

template <typename Base, typename Type, Type Base::* Var>
struct Member<Var>
{
    //stuff goes here
};

struct S
{
    int memberVal;
};

int main()
{
    Member<&S::memberVal> example;
};

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

没办法。只有您的第一个变体是正确的。您举例说明C ++ cyntax并不优雅。它是原样的。

您的第二个示例具有模板特化的语法。虽然它是新模板的定义。很可能这会被视为异议。

答案 1 :(得分:1)

您要求的内容无法直接在C ++中实现。限制是对于非类型模板参数,必须在模板定义中提供类型。类型推导仅适用于函数参数。

根据您的实际用例,可以使用其他替代方法,但它们意味着将成员指针从模板参数(编译时)移动到函数参数(运行时)。也就是说,给出一个类型:

template <typename C, typename M>
struct Member {
   M C::*ptr;
   Member( M C::*ptr ) : ptr(ptr) {}
};

可以使用以下语法创建它的实例:

auto x = create_member( &S::memberVal );

通过使用一些元编程技巧,虽然不是太复杂:

template <typename T> struct MemberType;
template <typename T, typename M> 
struct MemberType<M T::*> {
   typedef Member<T,M> type;
};
template <typename T>
typename MemberType<T>::type
create_member( T mbrptr ) {
    typename MemberType::type r(mbrptr);
    return r;
}

但正如我已经提到的,这意味着将编译时参数转换为运行时参数,从而可能会阻止编译器执行的某些优化(即内联)。