c++ - 是否有类似于/等同于 Functional Java 的 C++ 库?

标签 c++ boost functional-programming

是否有与优秀的Functional Java library 类似或等同的开源C++ 库? ?

具体功能包括:

  • 对可迭代对象或类似对象进行映射、 fold/缩减、过滤等
  • 选项类型
  • 不可变数据结构实现

(出于好奇,已经离开 C++ 多年)

是的,传统上认为其中一些功能需要垃圾回收。但是对于现代 C++ 功能和库,是否有人开始通过函数转换或其他方式传递托管指针?

更新 明确地说,我想知道是否存在与 Functional Java 类似的东西,因此以下可能是典型的语法:

// assumptions:
//   * my_list is a standard library iterable of ints
//   * f is a function of int that returns a std::string
//   * p is a predicate of std::string returning bool
//   * head_opt returns an option type
stream(my_list).map(f).filter(p).head_opt.get_or_else("None")

这是 Functional Java 提供的习惯用法,相信我,很容易习惯它...

最佳答案

正如@jalf所说,map和fold已经在标准中,隐藏在不同的名字后面:

  • map -> std::transform , 在 header 中找到 <algorithm>
  • fold -> std::accumulate , 在 header 中找到 <numeric>

可以在 Boost.Range 中找到更多功能性内容,这是一个非常棒的图书馆。特别是 range adaptors提供真正的功能性感觉,因为它们在其他范围内创建 View 。使用 C++11,还可以通过 lambda 轻松地即时创建可能的谓词。

Boost.Optional可能是您的“选项类型”,具体取决于您的意思。

C++ 中的不变性可以通过简单地声明您的对象来实现 const .您可以使用引用参数传递来避免复制。说实话,这当然不等同于真正的函数式不变性,因为函数式语言中的不变容器可以随心所欲地复制,并且通常只共享内部表示。毕竟,如果您从不写,写时复制就很棒。

关于您的托管指针,我不知道您所说的它们是什么意思。在 C++ 中,您通常根本不需要指针或动态分配的对象。只需“在堆栈上”创建它们:Foo obj; .

如果您指的是共享所有权,则有 std::shared_ptr .如果将这样的指针存储在容器中,甚至还有一个不错的范围适配器:

#include <boost/range/adaptor/indirected.hpp>
#include <boost/range/algorithm/generate.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <vector>
#include <memory>
#include <algorithm>
#include <iterator>
#include <iostream>

int main(){
  std::vector<std::shared_ptr<int>> v(5);
  int i = 0;
  boost::generate(v, [&i]{ return std::make_shared<int>(i++); });
  boost::copy(v | boost::adaptors::indirected,
      std::ostream_iterator<int>(std::cout));
}

你的具体例子

my_list.map(f).filter(p).head_opt.get_or_else("not found")

可以这样实现(注意 std::vector 是 C++ 中的默认容器):

// Warning, C++11 only!
// Boost.Range doesn't like lambdas without this:
#define BOOST_RESULT_OF_USE_DECLTYPE

#include <vector>
#include <string>
#include <iterator>
#include <iostream>
#include <boost/optional.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm/generate.hpp> // only needed for filling the vector
#include <boost/range/algorithm/copy.hpp> // only needed for printing

// we need a little helper for the optional stuff
struct head_opt_gen{} head_opt; // just a tag type

template<class Range>
auto operator|(Range const& r, head_opt_gen)
  -> boost::optional<decltype(r.front())>
{
  if(r.empty())
    return boost::none;
  return r.front();
}

int main(){
  using namespace boost::adaptors;
  std::vector<int> v(5);
  int i = 0;
  boost::generate(v, [&]()->int{ ++i; return i*i; });
  // first, without the optional stuff
  boost::copy(v | transformed([](int x){ return std::to_string(x); })
                | filtered([](std::string const& s){ return s.size() > 1; }),
      std::ostream_iterator<std::string>(std::cout, "\n"));
  std::cout << "=====================\n";
  // now with
  std::cout << boost::get_optional_value_or(
      v | transformed([](int x){ return std::to_string(x); })
        | filtered([](std::string const& s){ return s.size() > 2; }) // note: > 2
        | head_opt, "none");
}

使用 Clang 3.1 Trunk 编译,结果如下:

16
25
=====================
none

关于c++ - 是否有类似于/等同于 Functional Java 的 C++ 库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9439665/

相关文章:

android - 如何在 Kotlin 中实现 java SAM 接口(interface)?

arrays - 查找数组元素的所有唯一组合的最佳方法?

c++ - 嵌套类是类模板中的依赖类型?

c++ - 如何使用 boost::asio:write 调用发送 ICU UnicodeString?

c++ - errc::timed_out 类型的 boost 系统 make_error_code 具有 "Unkown error"消息

boost - 计算 Boost 库中的均值和矩

c++ 实现友元/内联函数

c++ - 给定一个不被复制的索引列表,将元素从一个 vector 复制到另一个 vector 的最有效方法

c++ - 对符号 'sem_close@@GLIBC_2.2.5' 的 undefined reference

java - 如何映射 "Try with resources"异常类型?