Most functional programming languages (e.g. Common Lisp, Scheme / Racket, Clojure, Haskell, Scala, Ocaml, SML) support some common higher-order functions on lists, such as map
, filter
, takeWhile
, dropWhile
, foldl
, foldr
(see e.g. Common Lisp, Scheme / Racket, Clojure side-by-side reference sheet, the Haskell, Scala, OCaml, and the SML documentation.)
Does C++11 have equivalent standard methods or functions on lists? For example, consider the following Haskell snippet:
let xs = [1, 2, 3, 4, 5]
let ys = map (\x -> x * x) xs
How can I express the second expression in modern standard C++?
std::list<int> xs = ... // Initialize the list in some way.
std::list<int> ys = ??? // How to translate the Haskell expression?
What about the other higher-order functions mentioned above?
Can they be directly expressed in C++?
1 Answer 1
Even more, C++ have such functions, take a look to algorithm (or with C++11 additions) header:
std::transform
std::for_each
std::remove_copy_if
They can be easily used with any container.
For example your code can be expressed like this (with C++11 lambdas for easy coding):
std::vector<int> x = {1, 2, 3, 4, 5};
std::vector<int> y;
std::transform(x.begin(), x.end(), std::back_inserter(y), [](int elem){ return elem * elem; });
Less intuitive, but you can easily wrap the std::transform
call into function which would return new container (with move
semantics for better perfomance).
-
Thanks. I'd like to simplify some code I wrote a few days ago and this could really help make it much shorter. Just one small question: why do you need to pass x.begin() and x.end()? Wouldn't be sufficient to just pass the vector x?Giorgio– Giorgio2012年10月18日 20:40:08 +00:00Commented Oct 18, 2012 at 20:40
-
std::transform
takes two iterators, so, you can take a slice of a container (remember that you have iterators arithmetics).m0nhawk– m0nhawk2012年10月18日 20:47:26 +00:00Commented Oct 18, 2012 at 20:47 -
So you have two operations in one: taking a slice, and applying a transformation.Giorgio– Giorgio2012年10月18日 20:48:40 +00:00Commented Oct 18, 2012 at 20:48
-
Formerly you have two iterators and applying transform to elements between them. Iterators not a common in functional programming.m0nhawk– m0nhawk2012年10月18日 20:49:22 +00:00Commented Oct 18, 2012 at 20:49
-
2I haven't met such libraries, in C++ the iterator-based algorithm much useful. You can make a wrapper of, in your case,
std::transform
like:Y<U> map(T<U>, std::function<Y(U)>)
.m0nhawk– m0nhawk2012年11月21日 11:44:10 +00:00Commented Nov 21, 2012 at 11:44
Explore related questions
See similar questions with these tags.
Data.Sequence
in Haskell? It's comparatively ugly.[a]
. You either have to hide the prelude function, hack around prelude, or choose a different and less intuitive name.Functor
,Foldable
, andTraversable
achieve this in as abstract a way as I can think.Data.Sequence
is an instance of all of these, so you can just dofmap (\x -> x * x) xs
.map
isfmap
specialized for beginners.