我正在尝试用c ++编写一个可变参数模板,它可以在编译时推断出类型,并为我提供任何指定的操作。例如,我希望对作为参数传递的相同类型的元素求和。这是我到目前为止的地方 -
template <typename T>
T sum(T &v) { return v; }
template <typename T, typename... Ts>
auto sum(T &v, Ts... rest) {
return v + sum(rest...);
}
用法 -
int a = sum(1,2,3);
要求 -
int a[] = {1,2,3};
sum(1,2,3,a); // Need to pass array of same type and get the result.
任何帮助将不胜感激。
答案 0 :(得分:1)
您可以使用以下内容:
template <typename T>
T sum(const T& v) { return v; }
// special case for array
template <typename T, std::size_t N>
T sum(const T (&v)[N]) { return std::accumulate(std::begin(v), std::end(v), T{}); }
template <typename T, typename... Ts>
auto sum(const T& v, const Ts&... rest) {
return sum(v) + sum(rest...);
}
答案 1 :(得分:0)
您的代码有一些const
和引用相关的错误,以及尝试使用无效数量的参数实例化same
模板。
要解决此问题,您需要使递归模板采用两个显式参数,以便您永远不会使用空参数包实例化same
:
template <typename T, typename... Ts>
struct same {
using type = typename same<T, typename same<Ts...>::type>::type;
};
template <typename T>
struct same<T, T> {
using type = T;
};
template <typename T>
T sum(const T &v) { return v; }
template <typename T, typename TT, typename... Ts>
typename same<T, TT, Ts...>::type sum(const T &v, const TT &w, const Ts&... rest) {
return sum(v) + sum(w,rest...);
}
然后,如果你仍想使用你的same
构造,但也支持数组解包,那么这样的东西应该有效:
template <typename T, typename... Ts>
struct same {
using type = typename same<T, typename same<Ts...>::type>::type;
};
template <typename T>
struct same<T, T> {
using type = T;
};
template <typename T, std::size_t N>
struct same<T, T[N]> {
using type = T;
};
template <typename T, std::size_t N>
struct same<T[N], T[N]> {
using type = T;
};
template <typename T, std::size_t N>
struct same<T[N], T> {
using type = T;
};
template <typename T>
T sum(const T &v) { return v; }
template <typename T, std::size_t N>
T sum(const T (&v)[N]) {
return std::accumulate(std::begin(v), std::end(v), T{});
}
template <typename T, typename TT, typename... Ts>
typename same<T, TT, Ts...>::type sum(const T &v, const TT &w, const Ts&... rest) {
return sum(v) + sum(w,rest...);
}
http://guides.rubyonrails.org/active_record_querying.html#scopes
您可以通过添加完美转发并尝试消除T
默认构造的必要性来改进该解决方案。