正如@jalf 所说,map 和 fold 已经在标准中,隐藏在不同的名称后面:
- map ->
std::transform,在标题 <algorithm> 中找到
- 折叠 ->
std::accumulate,在标题 <numeric> 中找到
更多功能性的东西可以在Boost.Range 中找到,这是一个非常棒的库。尤其是range adaptors 给人一种真正的功能感觉,因为它们在其他范围内创建视图。使用 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