Question

I'm working with pointer-to-member types inside templates, currently I have something like this going on:

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

But having to define Base, Type, and then Var, seems a little redundant, since Base and Type are implied in Var's type.

Is there some way to do this, such that, when using/calling the Member struct, it only needs to use the single pointer-to-member argument? Like, in theory, something like this:

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

struct S
{
    int memberVal;
};

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

Thanks for the help!

Was it helpful?

Solution

No way. Only your first variant is correct. You are giving example where the C++ cyntax is not that elegant. Bit it is as it is.

Your second example has syntax of a template specialization. While it is definition of a new template. Most likely this will be put as an objection.

OTHER TIPS

What you are asking for cannot be achieved in C++ directly. The limitation is that for non-type template arguments, the type must be provided in the template definition. Type deduction is only applied to function arguments.

Depending on your real use case, there are alternatives that can be done, but they imply moving the member pointer from being a template argument (compile time) to a function argument (runtime). That is, given a type:

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

It is possible to create instances of it with the syntax:

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

By using a few metaprogramming tricks, not too complex though:

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

But as I already mentioned, that means transforming the compile time argument into a runtime argument, and thus potentially inhibiting some of the optimizations that the compiler would do (namely inlining).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top