You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

向priority_queue<std::stringstream>推入元素时触发已删除构造函数错误如何解决?

解决std::priority_queue存储std::stringstream的编译错误

错误原因

你遇到的call to deleted constructor of 'std::basic_stringstream'错误,核心原因是std::stringstream的拷贝构造函数被显式删除。std::priority_queue在存储元素时需要执行拷贝(或移动)操作,直接存储stringstream对象会触发调用已删除的拷贝构造函数,导致编译失败。

能不能在优先队列中使用stringstream?

可以,但不能直接存储stringstream对象本身。有两种可行思路:要么改用存储格式化后的字符串(更贴合你的代码场景),要么用指针/智能指针间接存储stringstream。

修复方案

方案一:直接存储格式化后的字符串(推荐)

你的代码中,stringstream只是用来生成格式化字符串,后续操作仅依赖它的str()结果,完全没必要存储整个stream对象。这种方案最简洁高效:

  1. 修改makeString函数,返回生成的字符串而非stringstream:
std::string makeString(std::string name, std::string number) {
    std::stringstream ss;
    if (number.size() == 1) {
        ss << "0" << number << " - " << name << std::endl;
    } else {
        ss << number << " - " << name << std::endl;
    }
    return ss.str();
}
  1. 将优先队列改为存储std::string,并调整main中的逻辑:
int main(int argc, char const* argv[]) {
    std::string inputs;
    std::string priority;
    std::priority_queue<std::string> pqueue;

    while (true) {
        input("What do you want to do? ", inputs);
        if (inputs == "add") {
            input("Name: ", inputs);
            input("Priority: ", priority);
            std::string formatted_str = makeString(inputs, priority);
            std::cout << formatted_str;
            pqueue.push(formatted_str);
        } else if (inputs == "take") {
            std::cout << pqueue.top() << std::endl;
            pqueue.pop();
        } else if (inputs == "end") {
            return 0;
        } else {
            std::cout << inputs << " isn't a valid operation" << std::endl;
        }
    }
}

方案二:用智能指针间接存储stringstream(仅需保留stream状态时使用)

如果确实需要在队列中保留stringstream的可写入状态,可以使用std::unique_ptr(支持移动语义,无拷贝操作)来包装stringstream:

  1. 定义带自定义比较器的优先队列(默认按指针地址排序,不符合业务需求):
struct CompareStreamPtr {
    bool operator()(const std::unique_ptr<std::stringstream>& a, const std::unique_ptr<std::stringstream>& b) {
        // 此处逻辑决定优先级,示例为按字符串升序排列(大顶堆特性,a的字符串小于b时b优先出队)
        return a->str() < b->str();
    }
};

std::priority_queue<
    std::unique_ptr<std::stringstream>,
    std::vector<std::unique_ptr<std::stringstream>>,
    CompareStreamPtr
> pqueue;
  1. 调整add和take逻辑:
if (inputs == "add") {
    input("Name: ", inputs);
    input("Priority: ", priority);
    auto ss = std::make_unique<std::stringstream>();
    *ss << makeString(inputs, priority).str();
    std::cout << ss->str();
    pqueue.push(std::move(ss)); // 移动语义避免拷贝
} else if (inputs == "take") {
    auto& top_stream = pqueue.top();
    std::cout << top_stream->str() << std::endl;
    pqueue.pop();
}

总结

  • 优先选择方案一,它更贴合你的代码实际需求,代码简洁且性能更优。
  • 仅当需要在队列中保留stringstream的可操作状态时,才考虑方案二。

内容的提问来源于stack exchange,提问作者Vincent Reiley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 03:02:05