指向成员的变量参数模板参数

Gho*_*der 5 templates template-meta-programming c++11 c++14

是否可以将成员指针作为可变参数模板参数传递。我似乎无法弄清楚语法。

对于函数调用,其工作方式如下:

struct A
{
    int a;
    float b;
}

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

可以这样使用:

f(obj, &A::a, &A::b);
Run Code Online (Sandbox Code Playgroud)

我想以类似于类模板的方式传递参数

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

应该这样使用:

Foo<&A::a, &A::b> foo;
foo.bar(obj);
Run Code Online (Sandbox Code Playgroud)

我很难弄清楚应该是什么。

如果成员类型已知并且只有一个参数,则可以这样进行:

template <int A::*ptr> //...
Run Code Online (Sandbox Code Playgroud)

有没有一种方法可以针对成员指针具有不同的未知预先类型的成员指针的可变参数列表进行概括?

更新:固定已知类型的成员指针的可变参数包装如下声明:

template<int A::*...ptr> struct Foo {};
Run Code Online (Sandbox Code Playgroud)

现在,我只需要将int替换为可以推断出的typename即可。

在C ++ 17中,以下代码可以完美地工作:

template<auto A::*...ptr> struct Foo {};
Run Code Online (Sandbox Code Playgroud)

不幸的是,我需要一个适用于C ++ 14的解决方案

sky*_*ack 4

在 C++14 中,您可以使用另一级间接来做到这一点:

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);
}
Run Code Online (Sandbox Code Playgroud)

auto关键字(如您所提到的,随 C++17 引入用于非类型模板参数)或多或少解决了此类问题。想想std::integral_constant如果您不必每次都指定类型作为第一个参数,那么它会如何更加用户友好......