使用具有唯一指针向量的find算法

时间:2017-04-10 16:26:10

标签: c++

我有一个独特的指针向量。我正在使用移动语义添加它。这是部分类:

class execution_collection {
    typedef std::unique_ptr<execution> exec_ptr;
    typedef std::vector<exec_ptr> exec_ptr_vector;
    exec_ptr_vector executions;
    ...
public:
    ...
    double last_buy_fill_price(const std::string &) const;
    ...
};

当我尝试使用lambda std :: find_if时,我得到error: use of deleted function 'std::unique_ptr...。我不明白我在哪里试图复制ptr?

double execution_collection::last_buy_fill_price(const string &symbol) const {

    auto it = find_if(executions.begin(),executions.end(),
        [&symbol](exec_ptr ptr){
            return ptr->getSymbol() == symbol && ptr->getQuantity() > 0;
        });

    if (it != executions.end()) 
        return it->get()->getPrice();
    else
        return 0;
}

2 个答案:

答案 0 :(得分:2)

您正在尝试复制违反unique_ptr规则的unique_ptr。通过引用传递它。

[&symbol](const exec_ptr & ptr)
{
    return ptr->getSymbol() == symbol && ptr->getQuantity() > 0;
});

答案 1 :(得分:1)

使用一个小模板样板,我们可以说find调用的逻辑更具可读性,这样我们就可以这样写:

auto i = std::find_if(things.begin(), things.end(),
                      byContents(bySymbolWithQuantity("bar")));

你是否想要这当然是一种品味问题。

以下是一些实现此目的的代码:

#include <iostream>
#include <memory>
#include <vector>

struct Thing {
    Thing(std::string symbol, int quantity)
            : symbol(std::move(symbol)), quantity(quantity)
    {}

    auto getSymbol() const -> std::string const& { return symbol; }
    auto getQuantity() const -> int { return quantity; }

    std::string symbol;
    int quantity;
};

template<class Symbol>
auto bySymbolWithQuantity(Symbol&& symbol)
{
    return [symbol = std::forward<Symbol>(symbol)](auto&& thing) mutable -> decltype(auto)
    {
        return thing.getSymbol() == symbol and thing.getQuantity() > 0;
    };
}

template<class Pred>
auto byContents(Pred&& pred)
{
    return [pred = std::forward<Pred>(pred)](auto&& ptr, auto&&...args) mutable -> decltype(auto) {
        return pred(*ptr, args...);
    };
}


int main()
{
    std::vector<std::unique_ptr<Thing>> things;
    things.push_back(std::make_unique<Thing>("foo", 10));
    things.push_back(std::make_unique<Thing>("bar", 5));


    auto i = std::find_if(things.begin(), things.end(),
                          byContents(bySymbolWithQuantity("bar")));


    std::cout << (**i).getSymbol() << " : " << (**i).getQuantity() << std::endl;
}