我有一堆这样的结构,其中成员数量不断增加,但成员命名却保持一致:
struct one { int a; };
struct two { int a; int b; };
struct three { int a; int b; int c; };
我还有一个模板化函数,我想接受以下结构的成员之一:
template <typename T, typename ... ARGS> // T will be one, two, or three
void func(ARGS... args); // This should take 1, 2, or 3, int arguments respectively
我希望能够这样称呼它:
two foo;
func<two>(splatter(foo));
splatter
会以某种方式拆分foo
,以便解析为func<two>(foo.a, foo.b)
。
很明显,我可以不用splatter
来扩展此内联代码,但是我调用func
的代码本身很容易被模板化。我尝试使用initializer_list
,但是我不知道如何仅基于模板类型来构建一个。
不幸的是,我的编译器也不支持constexpr if
来发起对func
的调用或构建initializer_list
。我还有其他选择吗?
答案 0 :(得分:1)
据我所知,您所描述的内容无法使用c ++完成。或者,如果可以的话,那将是一个非常复杂的解决方案。原因是,您需要以某种方式存储指向类成员访问函数的指针,然后使用实际对象正确调用它们。
但是,您可以通过重载获得类似的功能,该功能易于实现。例如,您可以定义一个call_func
,以便为您的类型重载:
#include <array>
// types
struct one {
int a;
};
struct two {
int a;
int b;
};
struct three {
int a;
int b;
int c;
};
template <class T>
struct more_complex_type {
T a;
T b;
};
// template function
template <typename T, typename... ARGS>
auto func(ARGS... args) {
return std::array<T, sizeof...(args)>{args...};
}
// indirection overload
template <class T>
struct call_func_impl {};
template <>
struct call_func_impl<one> {
auto call(one val) { return func<int>(val.a); }
};
template <>
struct call_func_impl<two> {
auto call(two val) { return func<int>(val.a, val.b); };
};
template <>
struct call_func_impl<three> {
auto call(three val) { return func<int>(val.a, val.b, val.c); };
};
template <class T>
struct call_func_impl<more_complex_type<T>> {
auto call(more_complex_type<T> val) { return func<T>(val.a, val.b); };
};
// syntacting sugar
template <class T>
auto call_func(T val) {
return call_func_impl<T>{}.call(val);
}
// tests
auto test_func() { return func<int>(1, 2, 3, 4, 5); }
auto test_func_of_one() {
auto val = one{};
return call_func(val);
}
auto test_func_of_two() {
auto val = two{};
return call_func(val);
}
auto test_func_of_three() {
auto val = three{};
return call_func(val);
}
auto test_func_of_more_complex_type() {
auto val = more_complex_type<double>{};
return call_func(val);
}
此示例使用重载的结构模板包装函数调用。对于您的情况,这可能不是必需的,因为您没有模板类型。实际上,您可以重载call_func
。但是,这种方法允许您定义对more_complex_type
的调用,该调用已被模板化,因为在c ++中当前无法实现部分函数重载。