如果你可以基于N自动生成,我猜你可以编写代码来做你一般需要的东西(你试图使用可变参数的注释加强了这一点)。
事实上,你的函数也模板化在T
不幸的是复杂的东西比我想要的多一点。有比我要给出的更简单的解决方案,但是我看到的唯一的解决方案要求您明确指定类型,或者延迟检查可以在编译时完成的运行时。就目前而言,我能看到做你想做的事情的唯一方法就是使用可变参数模板。这得到你最想要的东西:
template <std::size_t N>
class System {
template <class ... Ts>
void fun(Ts& ts) {
static_assert(sizeof...(Ts) == N, "Wrong number of parameters!");
}
};
我的静态断言,而除非你打算有一个名为另一个成员函数,因为这是极不可能会有所作为,如果不是让,让事情变得简单(这fun
...不这样做)。现在,这个函数将只接受被N个参数调用,但它将允许所有类型改变。你希望他们都一样。所以我们需要一点TMP。
template <class ... Ts>
struct all_same{};
template <class T>
struct all_same<T> : std::true_type {
using same_type = T;
};
template <class T, class ... Ts>
struct all_same<T, T, Ts...> : all_same<T, Ts...> {};
template <class T1, class T2, class ... Ts>
struct all_same<T1, T2, Ts...> : std::false_type {};
一些经典的递归TMP得到了我们想要的。无论是包装中的所有类型是否相同,如果它们相同,我们都可以访问常见类型。一旦我们有一个共同的类型,已验证的大小,我们可以用包来初始化了一个数组和循环,所以我们不必继续做我们的函数中恼人的可变参数编程风格:
template <std::size_t N>
struct System {
template <class ... Ts>
void fun(Ts&... ts) {
static_assert(sizeof...(Ts) == N, "Wrong number of parameters!");
using same = all_same<Ts...>;
static_assert(same::value, "All types must be the same!");
std::array<std::reference_wrapper<typename same::same_type>, N> x{ts...};
for (auto& e : x) { std::cerr << e << std::endl; }
}
};
修改此解决方案以满足您的确切需求将需要C++的一些专业知识,并且您还需要关注我们的某些棘手情况,例如当你传递字符串文字和std::string
或其他类型时,你会习惯隐式转换,它会失败。不过,希望这可以帮助你继续下去。现场示例:http://coliru.stacked-crooked.com/a/08ac23da33deb8ef。
我不是100%确定你想要达到的目标,但是这种方法似乎是错误的IMO。你可能会用更好的运气来自动生成代码(例如:一个小脚本) – UnholySheep