我试图通过嵌套成员指针访问结构中的变量:
#include <iostream>
typedef struct {
int a;
int b;
} bar;
typedef struct {
int c;
bar d;
} baz;
template <typename obj, class C1, class C2, typename T1, typename T2>
T2 test1(const obj& obj_, T1 C1::* field1_, T2 C2::* field2_)
{
return (obj_.*field1_).*field2_;
}
int main()
{
baz myObj;
test1(myObj, &baz::d, &bar::b);
}
我如何将函数测试变成可变参数函数,以便我可以访问结构中变量“深度”处的变量? 我尝试按照函数参数列表部分中的第二个示例 here ,但我似乎没有明白:
template <typename obj, class ...C, typename... T>
void test2(const obj& obj_, T C...::* field_)
{
// ??
// and what about the function return parameter?
}
int main()
{
baz myObj;
test2(obj,&baz::d,&bar::b);
test2(obj,&baz::c);
}
这样,test2()
的定义就不会编译了。
可以使用任何(最新)版本的 C++(尽管使用 MSVC)。
出于测试目的,这里有一个 complete program on coliru .
解决方案
感谢Silvio's answer ,我能够解决它。利用 C++17,它还可以做得更短:
template <typename T, typename S, typename... Ss>
auto inline test2(const T& obj, S field1, Ss... fields)
{
if constexpr (!sizeof...(fields))
return obj.*field1;
else
return test2(obj.*field1, fields...);
}
最佳答案
可能有更简洁的方法来执行此操作,但您当然可以采用 C++ 模板非常喜欢的“将它扔到墙上,看看有什么粘住”的方法。
template <typename T>
auto test2(const T& obj) -> T {
return obj;
}
template <typename T, typename S, typename... Ss>
auto test2(const T& obj, S field1, Ss... fields)
-> decltype(test2(obj.*field1, fields...)) {
return test2(obj.*field1, fields...);
}
基本情况非常简单。如果我们不传递任何字段,我们只返回原始对象本身。递归的情况就是:我们递归。返回类型声明为...返回值的声明类型。参数类型只是变量。它们将根据需要完全实例化。如果您传递没有意义的参数或不进行类型检查,您将收到一些非常丑陋的错误消息。
关于c++ - 成员变量指针的函数参数包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51976201/