2014-12-30 2 views
4

Ниже приведен пример кода схемы (поправьте меня, если я ошибаюсь):C++: как сделать «карту» схемы

(define (translate points delta) 
    (map 
     (lambda (x) 
      (+ x delta) 
     ) 
     points 
    ) 
) 

в основном определяет функцию лямбда, что добавить delta для ввода x, затем примените его к каждому элементу points.

я нашел такую ​​возможность, довольно интересный, что он опускает все итераторы и т.д.

Можно ли сделать такое «карта» в C++, в элегантный способ?

Обновление в соответствии с ответом:

Чтобы быть более конкретным, есть способ реализовать такую ​​«карту» функцию схемы, в C++, так что она может быть использована элегантно? Может быть, функция шаблона с именем «карта», которая принимает указатель/функтор функции и контейнер?

ответ

1

Там нет предопределенного точного эквивалента ... но это не так трудно писать:

template<typename T, typename F> 
T mymap(const T& container, F f) { 
    T result; 
    for (auto const & x : container) { 
     result.push_back(f(x)); 
    } 
    return result; 
} 

std::vector<int> translate(const std::vector<int>& x, int delta) { 
    return mymap(x, [=](int x){return x+delta;}); 
} 

Нечто похожее на схему map является std::transform, но требует, чтобы обеспечить выходной итератор, где хранить преобразованные элементы.

Стандартная библиотека C++ построена вокруг концепции пар итераторов (например, даже для sort вы не пропускаете контейнер, а пару итераторов). Я лично не думаю, что это такая замечательная идея, но это то, как был разработан язык.

+0

спасибо, я думаю, это самый близкий к «карте» на Схеме – athos

2

Версия C++ называется std::transform.

4

Ближайший перевод кода в идиоматических C++ будет использовать std::transform с std::back_inserter:

std::vector<point> points{…}; 
std::vector<point> output; 
// optional, may improve performance: 
output.reserve(points.size()); 

auto lambda = [=](point x) { return x + delta; }; 
std::transform(begin(points), end(points), std::back_inserter(output), lambda); 

Здесь lambda захватывает окружающее его объем в стоимостном выражении - это обозначается префиксом [=]. Это позволяет использовать внутри него delta.

Однако для T -> T преобразований вы обычно используете вариант на месте вместо того, чтобы толкнуть значения в новый контейнер:

std::vector<point> points{…}; 

auto lambda = [=](point x) { return x + delta; }; 
std::transform(begin(points), end(points), begin(points), lambda); 
Смежные вопросы