Оболочка std :: transform с указателем на функцию-член и back_inserter - PullRequest
0 голосов
/ 04 мая 2018

Я создал оболочку для std :: transform, чтобы каждый раз не пропускать начало и конец.

template <typename C, typename C2, typename UnaryOperation>
void transform(const C& c1, C2& result, const UnaryOperation& up)
{
    std::transform(std::begin(c1), std::end(c1), std::begin(result), up);
}

Я могу использовать вот так

utils::transform(container, result, [](const auto& o) {return doSometing;});

Мне нужна еще одна подпись, где я мог бы сделать что-то вроде

struct X {
    Object foo(std::string const& ) const;

    void bar(std::vector<std::string> const& container) const
    {
        std::vector<Object> result;
        utils::transform(container, std::back_inserter(result), &X::foo);
        // do something with result
    }
};

Но это не работает. Что мне здесь не хватает? Что-то то в подписи? Как мне заставить это работать?

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

В вашем примере &X::foo - это функция, которая принимает два аргумента: явный (std::string const&) и неявный (X). Но ваш transform() хочет одинарный вызываемый. Там есть несоответствие.

Вам необходимо "привязать" неявный параметр объекта к &X::foo, чтобы он стал унарным. Самый простой способ сделать это с помощью лямбды:

utils::transform(container, std::back_inserter(result),
    [this](auto const& s) { return foo(s); });

Вы также можете использовать std::bind() ... но ... не надо.

0 голосов
/ 04 мая 2018

Вы можете использовать лямбду, как в первом примере использования.

Object object;
auto lambda_for_member_myFunction = [object](const auto& o) {
   return object.myFunction(o);
};
utils::transform(container, std::back_inserter(result), lambda_for_member);

Теперь вы можете обернуть это в другой помощник, но вам все равно нужно добавить object в качестве параметра.

...