Проблема в том, что лямбда не является std::function
, даже если она может быть преобразована.При выводе аргументов типа компилятору не разрешается выполнять преобразования для фактически предоставленных аргументов.Я бы искал способ, чтобы компилятор обнаружил тип U
и позволил компилятору освободить второй аргумент:
template <typename Container, typename Functor>
std::vector< XXX > VlcFunctional::map( Container &, Functor )...
Теперь вопрос в том, что написать в XXX.У меня нет того же компилятора, что и у вас, и все возможности C ++ 0x все еще немного хитры.Сначала я попытался бы использовать decltype
:
template <typename Container, typename Functor>
auto VlcFunctional::map( Container & c, Functor f ) -> std::vector< decltype(f(*c.begin())) > ...
Или, может быть, набирать черты, если компилятор еще не поддерживает decltype
.
Также обратите внимание, что код, который вы пишете, довольнооднотипный в C ++.Обычно при манипулировании контейнерами функции реализуются в терминах итераторов, и вся ваша карта в основном является старой std::transform
:
std::vector<int> v = { 1, 2, 3, 4, 5 };
std::vector<std::string> s;
std::transform( v.begin(), v.end(), std::back_inserter(s), [](int x) { return ToString(x); } );
, где std::transform
- версия вашей функции map
на C ++.Хотя синтаксис является более громоздким, преимущество заключается в том, что вы можете применить его к любому контейнеру и создать выходные данные для любого другого контейнера, поэтому преобразованный контейнер не фиксируется на std::vector
.
РЕДАКТИРОВАТЬ: Третий подход, который, вероятно, проще реализовать с вашей текущей поддержкой компилятора, вручную предоставляет только тип возвращаемого значения лямбды в качестве аргумента шаблона и позволяет компилятору выводить остальное:
template <typename LambdaReturn, typename Container, typename Functor>
std::vector<LambdaReturn> map( Container const & c, Functor f )
{
std::vector<LambdaReturn> ret;
std::transform( c.begin(), c.end(), std::back_inserter(ret), f );
return ret;
}
int main() {
std::vector<int> v{ 1, 2, 3, 4, 5 };
auto strs = map<std::string>( v, [](int x) {return ToString(x); });
}
Даже еслиВы хотите добавить синтаксический сахар в вашу функцию map
, нет необходимости вручную ее реализовывать, когда вы можете использовать существующие функции.