C++ 从对象的向量返回一个对象作为引用 #包括 #包括 #包括 #包括 #包括 #包括 #包括 名称空间范围=标准::范围; 结构模型 { 加倍下一个事件的时间; }; 双时间(整数重复、整数项、标准::函数func) { 自动开始=标准::计时::稳定时钟::现在(); 用于(自动i=0;i

C++ 从对象的向量返回一个对象作为引用 #包括 #包括 #包括 #包括 #包括 #包括 #包括 名称空间范围=标准::范围; 结构模型 { 加倍下一个事件的时间; }; 双时间(整数重复、整数项、标准::函数func) { 自动开始=标准::计时::稳定时钟::现在(); 用于(自动i=0;i,c++,c++20,C++,C++20,不能从常量向量返回非常量模型引用。使用常量模型&返回类型,或者在获取下一个模型2中声明模型参数,而不使用常量关键字 #include <iostream> #include <vector> #include <random> #include <ranges> #include <algorithm> #include <chrono> #include <functional> namespace ran

不能从
常量向量
返回非常量模型引用。使用
常量模型&
返回类型,或者在
获取下一个模型2
中声明
模型
参数,而不使用
常量
关键字

#include <iostream>
#include <vector>
#include <random>
#include <ranges>
#include <algorithm>
#include <chrono>
#include <functional>


namespace ranges = std::ranges;

struct Model
{
    double next_event_time;
};

double timeit(int repeats, int items, std::function<void(int)> func)
{
    auto begin = std::chrono::steady_clock::now();
    for (auto i = 0; i < repeats; i++)
        func(items);
    auto end = std::chrono::steady_clock::now();
    auto dur = (end - begin);

    auto total_time = std::chrono::duration_cast<std::chrono::microseconds>(dur);

    return total_time.count() / repeats;
}

std::vector<Model> generate_examples(int number)
{

    std::default_random_engine generator;

    std::uniform_real_distribution<double> distribution(0.0, 1.0);

    std::vector<Model> models;

    for (auto i = 0; i < number; i++)
    {
        models.push_back(Model{.next_event_time = distribution(generator)});
    }

    return models;
}

Model& get_next_model(std::vector<Model> &models)
{
    ranges::sort(models, ranges::less{}, [](const Model &x) { return x.next_event_time; });

    return models[0];
}

Model& get_next_model2(const std::vector<Model> &models)
{
    // Error here 
    return ranges::min(models, ranges::less{}, [](const Model &x) { return x.next_event_time; });
}

void timeOne(int items)
{
    std::vector<Model> models = generate_examples(items);

    get_next_model(models);
}

void timeTwo(int items)
{
    auto models = generate_examples(items);
    get_next_model2(models);
}

int main()
{
    const std::string MS_UNIT = "[ms]";
    int items = 1000;
    int repeats = 10000;

    //std::cout << timeit(repeats, items, timeOne) << MS_UNIT << std::endl;
    std::cout << timeit(repeats, items, timeTwo) << MS_UNIT << std::endl;
    return 0;
}

Model&get\u next\u model2(std::vector&models)
或:

const Model&get\u next\u model2(const std::vector&models)

接受任意范围的
std::ranges::min
重载按值返回。因为它返回临时值,所以不能将非常量左值引用绑定到其返回值。即使可以,只要返回
get\u next\u model2
,该引用就会挂起

改为使用。
min\u元素
将迭代器返回到某个范围内的最小值。请注意,如果要从
get\u next\u model2
返回非常量引用,则需要接受对
std::vector
的非常量引用,因为
const
向量的元素本身都是
const

const Model& get_next_model2(const std::vector<Model> &models)
Model&get\u next\u model2(std::vector&models)
{
返回*范围::最小元素(
模型,
范围::小于{},
[](const Model&x){return x.next_event_time;}
);
}

如果
models
为空,则取消对
min\u元素()返回值的引用
给出了未定义的行为。最好在取消引用之前检查一下。@PatrickRoberts我很抱歉,谢谢你能将此评论作为一个答案移动到please吗?这只是为了你的利益,你不需要取消删除该问题。反正我也不准备写详细的解释。
const Model& get_next_model2(const std::vector<Model> &models)
Model& get_next_model2(std::vector<Model> &models)
{
    return *ranges::min_element(
        models,
        ranges::less{},
        [](const Model &x) { return x.next_event_time; }
    );
}