使用带有可变参数函数的初始化列表
Using initialization list with variadic function
我用模板元编程快速编写了一个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");
}
http://ideone.com/nM8HH3
#include <iostream>
#include <functional>
#include <initializer_list>
template<typename Functor, typename T, size_t N>
T constexpr reduce(Functor f, T(&arr)[N]) {
typename std::remove_const<T>::type val = arr[0];
for(auto i = std::begin(arr)+1; i != std::end(arr); ++i) val = f(val, *i);
return val;
}
template<typename Functor, typename T>
T constexpr reduce(Functor f, std::initializer_list<T> il) {
T val = *il.begin();
for(auto i = il.begin()+1; i != il.end(); ++i) val = f(val, *i);
return val;
}
template<typename Functor, typename T, typename... Ts>
T constexpr reduce(Functor f, T t1, Ts... ts) {
return f(t1, reduce(f, std::initializer_list<T>({ts...})));
}
template<int value>
void print_constexpr() { std::cout << value << std::endl; }
int main() {
// run-time or compile-time
std::cout << reduce(std::plus<int>(), 1, 2, 3, 4, 5, 6, 7) << std::endl; // 28
std::cout << reduce(std::plus<int>(), {1, 2, 3, 4, 5, 6, 7}) << std::endl;// 28
const int input[3] = {1, 2, 3}; // 6
std::cout << reduce(std::plus<int>(), input) << std::endl;
// compile-time
print_constexpr< reduce(std::plus<int>(), 1, 2, 3, 4, 5, 6, 7) >(); // 28
print_constexpr< reduce(std::plus<int>(), {1, 2, 3, 4, 5, 6, 7}) >(); // 28
constexpr int input_constexpr[3] = {1, 2, 3}; // 6
print_constexpr< reduce(std::plus<int>(), input_constexpr) >(); // 6
return 0;
}
输出:
28
28
6
28
28
6
您可以在编译时使用以下任何一种:
-
reduce(std::plus<int>(), 1, 2, 3, 4, 5, 6, 7)
-
reduce(std::plus<int>(), {1, 2, 3, 4, 5, 6, 7})
-
reduce(std::plus<int>(), input)
使用任何constexpr
函子。
相关文章:
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 如何在 C++ 中使用它的构造函数初始化 unique_ptrs 的 2D 向量?
- 我们是否需要为 C++ 中的多个函数初始化多个模板?
- 在C++中使用默认构造函数初始化对象的不同方法
- 使用默认构造函数初始化对象的不同方法
- 我们可以用参数化构造函数初始化结构的数组吗?
- 有没有办法使用该类的构造函数初始化另一个类的私有部分内的对象数组?
- 类内初始化与构造函数初始化列表的顺序
- 通过 C++ 中的重载构造函数初始化未知类型的变量
- 使用复制构造函数初始化 new[]
- 如何从子类的构造函数初始化父类的私有成员
- 在构造函数初始化列表中使用 std::variant
- 使用构造函数初始化结构还是在之后设置其值更好?
- C++ 没有匹配的构造函数初始化 []
- 我正在使用dev c ++,但收到错误(C++98'array'必须由构造函数初始化)
- 如何从静态类函数初始化静态类对象
- 使用所述填充构造函数初始化向量中的向量
- 如何同时创建一个具有两个或多个构造函数初始化的对象
- 使用 c++ 中的函数初始化数组
- 使用 lambda 函数初始化静态数据成员