Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从基于两个变量的结构向量中获取的最小元素_C++_Vector_Struct_Std - Fatal编程技术网

C++ 从基于两个变量的结构向量中获取的最小元素

C++ 从基于两个变量的结构向量中获取的最小元素,c++,vector,struct,std,C++,Vector,Struct,Std,因此,我有一个结构向量,它的定义和使用方式如下: enum ID { alpha, beta, gamma }; using TimePoint = std::chrono::time_point<std::chrono::system_clock>; typedef struct pInfo { int bar; int key; ID id; TimePoint tPoint; } pInfo; std::vector

因此,我有一个结构向量,它的定义和使用方式如下:

enum ID {
    alpha,
    beta,
    gamma
};

using TimePoint = std::chrono::time_point<std::chrono::system_clock>;

typedef struct pInfo {
    int bar;
    int key;
    ID id;
    TimePoint tPoint;
} pInfo;

std::vector<pInfo> pMembers;
但这并不能解释为什么我只想得到某些类型


我将如何执行类似操作?

使lambda捕获传递的ID,以便在比较中使用它,例如:

pInfo& getNext(ID p_id)
{
    if (pMembers.empty())
        throw ...; // nothing to search, can't return a reference to nothing, so throw an exception instead...

    auto iter = std::min_element(std::begin(pMembers), std::end(pMembers),
        [=](const pInfo &lhs, const pInfo &rhs)
        {
            if (lhs.id == p_id) {
                if (rhs.id != p_id) return true;
            }
            else if (rhs.id == p_id) {
                if (lhs.id != p_id) return false;
            }
            else {
                return false;
            }
            return lhs.tPoint < rhs.tPoint;
        }
    );

    if (iter->id != p_id)
        throw ...; // p_id not found, can't return a reference to nothing, so throw an exception instead...

    return *iter;
}
或者,尝试类似以下内容:

std::min_element(std::begin(pMembers), std::end(pMembers), [](auto&& lhs, auto&& rhs){return lhs.tPoint < rhs.tPoint};
pInfo& getNext(ID p_id)
{
    std::vector<std::reference_wrapper<pInfo>> v;

    std::copy_if(std::begin(pMembers), std::end(pMembers), std::back_inserter(v),
        [=](const pInfo &item){ return item.id == p_id; }
    );
    if (v.empty())
        throw ...; // p_id not found, can't return a reference to nothing, so throw an exception instead...

    auto iter = std::min_element(std::begin(v), std::end(v),
        [](const pInfo &lhs, const pInfo &rhs){ return lhs.tPoint < rhs.tPoint; }
    );
    return *iter;
}

使lambda捕获传递的ID,以便在比较中使用它,例如:

pInfo& getNext(ID p_id)
{
    if (pMembers.empty())
        throw ...; // nothing to search, can't return a reference to nothing, so throw an exception instead...

    auto iter = std::min_element(std::begin(pMembers), std::end(pMembers),
        [=](const pInfo &lhs, const pInfo &rhs)
        {
            if (lhs.id == p_id) {
                if (rhs.id != p_id) return true;
            }
            else if (rhs.id == p_id) {
                if (lhs.id != p_id) return false;
            }
            else {
                return false;
            }
            return lhs.tPoint < rhs.tPoint;
        }
    );

    if (iter->id != p_id)
        throw ...; // p_id not found, can't return a reference to nothing, so throw an exception instead...

    return *iter;
}
或者,尝试类似以下内容:

std::min_element(std::begin(pMembers), std::end(pMembers), [](auto&& lhs, auto&& rhs){return lhs.tPoint < rhs.tPoint};
pInfo& getNext(ID p_id)
{
    std::vector<std::reference_wrapper<pInfo>> v;

    std::copy_if(std::begin(pMembers), std::end(pMembers), std::back_inserter(v),
        [=](const pInfo &item){ return item.id == p_id; }
    );
    if (v.empty())
        throw ...; // p_id not found, can't return a reference to nothing, so throw an exception instead...

    auto iter = std::min_element(std::begin(v), std::end(v),
        [](const pInfo &lhs, const pInfo &rhs){ return lhs.tPoint < rhs.tPoint; }
    );
    return *iter;
}

我只是将具有不同ID的对象存储在不同的向量中,每个ID对应一个向量:

std::map<ID, std::vector<pInfo>> pMembers;
如果您不能或不愿这样做,那么我将使用过滤迭代器适配器。以下示例使用Boost.Iterator:

auto const filter = [p_id](auto const& id) { return id == p_id; };
auto const compare = [](auto const& a, auto const& b) { return a.tPoint < b.tPoint; };

auto const it = std::min_element(boost::make_filter_iterator(filter, begin(pMembers), end(pMembers)),
                                 boost::make_filter_iterator(filter,   end(pMembers), end(pMembers)),
                                 compare).base();
根据Remy的回答,我将这样写他们的第一种方法:

auto const it = std::min_element(begin(pMembers), end(pMembers), [=](auto const& a, auto const& b)
{
    return std::forward_as_tuple(a.id != p_id, a.tPoint)
         < std::forward_as_tuple(b.id != p_id, b.tPoint);
});

我只是将具有不同ID的对象存储在不同的向量中,每个ID对应一个向量:

std::map<ID, std::vector<pInfo>> pMembers;
如果您不能或不愿这样做,那么我将使用过滤迭代器适配器。以下示例使用Boost.Iterator:

auto const filter = [p_id](auto const& id) { return id == p_id; };
auto const compare = [](auto const& a, auto const& b) { return a.tPoint < b.tPoint; };

auto const it = std::min_element(boost::make_filter_iterator(filter, begin(pMembers), end(pMembers)),
                                 boost::make_filter_iterator(filter,   end(pMembers), end(pMembers)),
                                 compare).base();
根据Remy的回答,我将这样写他们的第一种方法:

auto const it = std::min_element(begin(pMembers), end(pMembers), [=](auto const& a, auto const& b)
{
    return std::forward_as_tuple(a.id != p_id, a.tPoint)
         < std::forward_as_tuple(b.id != p_id, b.tPoint);
});

您也可以简单地将基于的范围应用于此问题,如下所示:


您也可以简单地将基于的范围应用于此问题,如下所示:


返回iter->get的最后一行;抛出一个错误。返回iter->get的最后一行;抛出一个错误。