在可变参数模板中包含相同类型的数组

Including Array of same type in Variadic Templates

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

任何帮助将不胜感激。

您可以使用以下内容:

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

Live demo

您的代码有一些 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...);
}

Demo

您可以通过添加完美转发并尝试消除 T 成为默认构造的必要性来改进该解决方案。