Краткая версия моего вопроса такова: как я могу использовать что-то вроде std::bind()
со стандартным алгоритмом библиотеки?Как `std :: bind()` стандартный алгоритм библиотеки?
Поскольку короткая версия немного лишена деталей, вот немного объяснения: Предположим, у меня есть алгоритмы std::transform()
и теперь я хочу реализовать std::copy()
(да, я понимаю, что есть в стандартной библиотеки C++ std::copy()
). Поскольку я ужасно ленив, я явно хочу использовать существующую реализацию std::transform()
. Я мог бы, конечно, сделать это:
struct identity {
template <typename T>
auto operator()(T&& value) const -> T&& { return std::forward<T>(value); }
};
template <typename InIt, typename OutIt>
auto copy(InIt begin, InIt end, OutIt to) -> OutIt {
return std::transform(begin, end, to, identity());
}
Каким-то образом эта реализация несколько чувствует себя конфигурации алгоритма. Так, например, кажется, что std::bind()
должен быть в состоянии сделать эту работу, но просто с помощью std::bind()
не работает:
namespace P = std::placeholders;
auto copy = std::bind(std::transform, P::_1, P::_2, P::_3, identity());
Проблема заключается в том, что компилятор не может определить соответствующие аргументы шаблона из всего алгоритма и не имеет значения, есть ли &
или нет. Есть ли что-то, что может сделать такой подход, как использование std::bind()
? Поскольку это с нетерпением ждет, я доволен решением, работающим со всем, что уже предлагается для включения в стандарт C++. Кроме того, чтобы уйти с моей леностью, я счастлив сделать некоторые работы перед тем, чтобы более легко использовать их. Подумайте об этом так: в моей роли библиотеки исполнитель, я собираюсь собрать вещи один раз, так что всякая библиотека пользователь может быть ленивой: я занят реализацией, но ленивым пользователем.
Если у вас есть готовая тестовая кровать: вот полная программа.
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <utility>
#include <vector>
using namespace std::placeholders;
struct identity {
template <typename T>
T&& operator()(T&& value) const { return std::forward<T>(value); }
};
int main()
{
std::vector<int> source{ 0, 1, 2, 3, 4, 5, 6 };
std::vector<int> target;
#ifdef WORKS
std::transform(source.begin(), source.end(), std::back_inserter(target),
identity());
#else
// the next line doesn't work and needs to be replaced by some magic
auto copy = std::bind(&std::transform, _1, _2, _3, identity());
copy(source.begin(), source.end(), std::back_inserter(target));
#endif
std::copy(target.begin(), target.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n";
}
@ πάνταῥεῖ: Эй, это неподдельный вопрос ...! (конечно, двойные цели действительно играют определенную роль) –
Комбинация тегов была, что заставило меня подозревать ;-) ... (и это, конечно, хороший вопрос) –
Общий лямбда - это почти единственное, что я могу придумать, но Я предполагаю, что недостаточно 'bind'-like ... –