std::transform 带有指向成员函数指针的包装器和 back_inserter

std::transform wrapper with pointer to member functionand back_inserter

我为 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
    }
};

但这行不通。我在这里错过了什么?签名里的东西?我如何让它发挥作用?

您可以像在第一个用法示例中那样使用 lambda。

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 作为参数。

在你的例子中 &X::foo 是一个接受 两个 参数的函数:一个显式参数(std::string const&)和一个隐式参数(X).但是您的 transform() 想要一个 unary 可调用对象。那里不匹配。

您需要 "bind" 将隐式对象参数 &X::foo 设为一元。最简单的方法是使用 lambda:

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

您也可以使用 std::bind()...但是...不要。