13

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++?

8
  • Yes, but they operate on more general concepts than that specific implementation of a doubly linked list. As do Python's operations in this area. I much prefer that to being tied to a specific data structure. Ever tried to do these operations on, say, a Data.Sequence in Haskell? It's comparatively ugly.
    – user7043
    Commented Oct 18, 2012 at 20:17
  • "It's comparatively ugly.": Compared to what?
    – Giorgio
    Commented Oct 18, 2012 at 20:19
  • Compared to the same operation on [a]. You either have to hide the prelude function, hack around prelude, or choose a different and less intuitive name.
    – user7043
    Commented Oct 18, 2012 at 20:21
  • Maybe you are right, but the topic of this question is how to express common list higher-order functions in C++, not how to implement analogous functions on Data.Sequence in Haskell.
    – Giorgio
    Commented Oct 18, 2012 at 20:23
  • 1
    @delnan I would argue that Haskell is much more general in its approach. Functor, Foldable, and Traversable achieve this in as abstract a way as I can think. Data.Sequence is an instance of all of these, so you can just do fmap (\x -> x * x) xs. map is fmap specialized for beginners.
    – Alec
    Commented Jul 23, 2015 at 14:22

1 Answer 1

17

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).

10
  • 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
    Commented 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
    Commented Oct 18, 2012 at 20:47
  • So you have two operations in one: taking a slice, and applying a transformation.
    – Giorgio
    Commented 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
    Commented Oct 18, 2012 at 20:49
  • 2
    I 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
    Commented Nov 21, 2012 at 11:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.