我在模板中使用指向成员类型的指针,目前我还有这样的事情:
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;
};
感谢您的帮助!
答案 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;
}
但正如我已经提到的,这意味着将编译时参数转换为运行时参数,从而可能会阻止编译器执行的某些优化(即内联)。