c++ - 使用可变参数函数的初始化列表

标签 c++ variadic-templates variadic-functions initialization-list

我很快用模板元编程写了一个reduce函数。我知道它并不完美,我应该检查类型是否兼容,返回类型...

#include <iostream>
#include <functional>

template <typename Functor, typename T>
T reduce(Functor f, T v) {
  return v;
}

template<typename Functor, typename T1, typename... Ts>
T1 reduce(Functor f, T1 t1, Ts... ts) {
  return f(t1, reduce(f, ts...));
}

int main() {
  std::cout << reduce(std::plus<int>(), 1, 2, 3, 4, 5, 6, 7) << std::endl;
  return 0;
}

关键是我想写这样的东西

std::cout << reduce(std::plus<int>(), {1, 2, 3, 4, 5, 6, 7}) << std::endl;

或者如果可能的话

const int input[3] = {1, 2, 3};
std::cout << reduce(std::plus<int>(), input) << std::endl;

最佳答案

您不需要可变参数模板:

#include <algorithm>
#include <iostream>
#include <iterator>

namespace Detail {
    template <typename Functor, typename List>
    typename Functor::result_type reduce(Functor f, const List& list) {
        using std::begin;
        using std::end;
        typename Functor::result_type result{};
        auto pos = begin(list);
        if(pos != end(list)) {
            result = *pos;
            while(++pos != end(list))
                result = f(result, *pos);
        }
        return result;
    }
} // namespace Detail

template <typename Functor, typename List>
typename Functor::result_type reduce(Functor f, const List& list) {
    return Detail::reduce(f, list);
}

template <typename Functor, typename T>
typename Functor::result_type reduce(Functor f, std::initializer_list<T> list) {
    return Detail::reduce(f, list);
}

int main () {
    std::cout << reduce(std::plus<int>(), {1, 2, 3, 4, 5, 6, 7}) << std::endl;
    const int input[3] = {1, 2, 3};
    std::cout << reduce(std::plus<int>(), input) << std::endl;
}

使用“constexpr”的 C++11 (g++ 4.8.4) 变体:

#include <algorithm>
#include <iostream>
#include <iterator>

// constexpr plus is C++14
template<typename T>
struct plus : public std::binary_function<T, T, T>
{
  constexpr T operator()(const T& x, const T& y) const { return x + y; }
};

// constexpr begin is C++14
template<class T, std::size_t N>
inline constexpr T* begin(T (&array)[N]) { return array; }

// constexpr end is C++14
template<class T, std::size_t N>
inline constexpr T* end(T (&array)[N]) { return array + N; }

template <typename Functor, typename Iterator>
inline constexpr typename Functor::result_type
reduce(
    const Functor& f,
    const typename Functor::result_type& value,
    Iterator first, 
    Iterator last)
{
    return (first != last)
        ? reduce(f, f(value, *first), first + 1, last)
        : value;
}

template <typename Functor, typename T, std::size_t N>
constexpr typename Functor::result_type reduce(const Functor& f, T (&array)[N]) {
    // constexpr begin/end is C++14
    // using std::begin;
    // using std::end;
    return reduce(f, typename Functor::result_type{}, begin(array), end(array));
}

template <typename Functor, typename T>
inline constexpr typename Functor::result_type reduce(
    const Functor& f,
    std::initializer_list<T> list)
{
    return reduce(f, typename Functor::result_type{}, list.begin(), list.end());
}

int main () {
    static constexpr int input[3] = {1, 2, 3};
    static_assert(28 == reduce(plus<int>(), {1, 2, 3, 4, 5, 6, 7}), "Failure");
    static_assert(6 == reduce(plus<int>(), input), "Failure");
}

关于c++ - 使用可变参数函数的初始化列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36073757/

相关文章:

c++ - 帮助组装/SSE 乘法

c++ - 编译错误,未创建函数/方法!对于 brms 模型

c++ - 使用循环显示数组时,没有任何作用

c++ - MFC 应用程序的退出函数在哪里?

c++ - 当构造函数具有相同的参数类型(文件路径)时,如何从数组创建(初始化)std::tuple

c++ - 可变参数模板包扩展参数 id

c++ - 模板可变函数 : arbitrary number of classes with arbitrary number of constructor parameters

c++ - 类型、整型常量和模板模板参数的可变参数模板

c++ - 可变参数到 lambda 表达式

我可以在 "... "之前传递数组类型吗?在哪里可以找到 va_* 的宏代码