【问题标题】:Pointers to member as variadic template parameters指向成员的指针作为可变参数模板参数
【发布时间】:2017-10-20 00:09:24
【问题描述】:

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

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

struct A
{
    int a;
    float b;
}

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

可以这样使用:

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

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

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

应该这样使用:

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

我无法弄清楚 [something] 应该是什么。

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

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

有没有办法将其概括为成员指针的可变参数列表,其中成员具有不同的未知预先类型?

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

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

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

对于 C++17,以下工作完美:

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

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

【问题讨论】:

  • 可能是template&lt;typename... T, T A::*ptr...&gt;?
  • 很遗憾,它无法编译

标签: c++11 templates c++14 template-meta-programming


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    相关资源
    最近更新 更多