在Variadic模板中包含相同类型的数组

时间:2015-05-12 14:03:34

标签: c++ variadic-templates variadic-functions

我正在尝试用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.

任何帮助将不胜感激。

2 个答案:

答案 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...);
}

operator()

答案 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默认构造的必要性来改进该解决方案。