6

Is it possible to pass pointers-to-member as variadic template arguments. I can't seem to figure out the syntax.

for a function call it works like this:

struct A
{
    int a;
    float b;
}

template <typename ... TArgs> void f(A *obj, TArgs ... params)
{
    void *members[] { (&(obj->*params))... };
    // ... do something ...
}

That can be used like this:

f(obj, &A::a, &A::b);

I would like to pass params in a similar fashion to a class template

template <[something] ... params> class Foo
{
    void Bar(A *obj)
    {
        void *members[] { (&(obj->*params))... };
        // ... do something ...
    }
};

That should be used like this:

Foo<&A::a, &A::b> foo;
foo.bar(obj);

I'm having trouble figuring out what [something] should be.

If member type is known and there is only one parameter, it can be done like this:

template <int A::*ptr> //...

Is there a way to generalize this for variadic parameter list of member pointers where members are of different unknown beforehand types?

Update: Variadic argument pack for member pointers of fixed known types is declared like so:

template<int A::*...ptr> struct Foo {};

Now I just need to replace int with typename that can be deduced.

And with C++17, following works perfectly:

template<auto A::*...ptr> struct Foo {};

Unfortunately I need a solution that will work with C++14

2
  • Maybe template<typename... T, T A::*ptr...>? Commented May 19, 2017 at 19:26
  • Unfortunately, it doesn't compile Commented May 19, 2017 at 20:07

1 Answer 1

4

In C++14, you can use another level of indirection to do that:

struct A {
    int a;
    float b;
};

template<typename... T>
struct Bar {
    template <T A::*... params>
    struct Foo {
        void Bar(A *obj) {
            void *members[] { (&(obj->*params))... };
            // ... do something ...
            (void)members;
        }
    };
};

int main() {
    A a;

    Bar<int, float>::Foo<&A::a, &A::b> foo;
    foo.Bar(&a);
}

auto keyword (introduced with the C++17 for non-type template parameters, as you mentioned) solves more or less this kind of issues. Think of std::integral_constant and how would it be more user-friendly if you hadn't to specify each time the type as the first argument...

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.