首页 > 解决方案 > C++ 模板元编程,使用可变参数模板执行结构特定成员的操作

问题描述

我开发了这种方法,同时找到了一种将结构很好地抽象绑定到 SQLite 包装器的 SQL 语句的方法,我的目标是能够抽象出大部分绑定过程以及能够“别名”专用函数模板这样您就不需要在每次使用时重新键入绑定。

auto我找到的方法将在 clang 上编译,但由于使用了在下面的示例中复制的关键字,我目前无法让它同时适用于 GCC 和 MSVC add_2

例子:

// final function to perform the addition on each member
template<class T, class M>
void add2_member(T& value, M member)
{
    value.*member += 2;
}

// variadic template function that unpack the Members and calls add2_member for each
// arg in args using c++17 fold syntax.
template<class T, auto T::*... Members>
void add2(T& value)
{
    (add2_member(value, Members), ...);
}

// example struct X
struct X
{
    int a;
    int b;
    char c;
};

// alias add2 function specialisation
auto add2_x = add2<X, &X::a, &X::c>;

int main()
{
    X x;
    x.a = 2;
    x.c = 1;
    add2_x(x);
}

显示这项工作的实时链接在这里,它显示了 godolt 使用 Clang 9 编译的示例,但是 GCC 无法推断出汽车的类型,我目前还没有找到一种方法来实现我的目标,这可能是使用宏完成。

标签: c++language-lawyermetaprogramming

解决方案


感谢Sam Varshavchik的解决方案。

MSVC 和 GCC 现在都能够编译这段代码并推断出 auto 类型,不过对于 MSVC,你记得要传递/Zc:auto.

template<class T, class M>
void add2_member(T& value, M member)
{
    value.*member += 2;
}

template<class T, auto ... Members>
void add2(T& value)
{
    (add2_member(value, Members), ...);
}

推荐阅读