【问题标题】:Range-based loop for std::queuestd::queue 的基于范围的循环
【发布时间】:2014-01-11 14:47:22
【问题描述】:

我正在尝试在我的项目中寻找 std::vector 的替代品,我发现 std::queue 是我正在寻找的。​​p>

我有很多使用range-based loop 进行迭代的函数,我正在尽可能地对其进行维护。

我尝试在std::queue 中编译range-based loop,但我得到的只是编译错误

错误:没有匹配函数调用'begin(std::queue&)'

std::queue 不支持范围基循环吗?

我确实尝试了Google search,但没有找到任何与此相关的主题。

更新:

我的编译器是GCC v4.7.1

-std=c++11 已启用

这是错误的测试代码:

std::queue<int> Q;

for (int i = 0;i < 10; ++i)
    Q.push(i);

std::cout << "\nqueue contains: ";
for (auto i : Q)
    std::cout << i << ", ";

【问题讨论】:

  • 对于未来的问题,您可以尝试在http://ideone.com 等在线编译环境中构建您的测试用例,如果您有编译器问题,它会立即通知您。在这里,ideone.com/kIln7G 它给出了你提到的同样的错误
  • @mr5 好的,gcc 4.8.1 和 clang++ 3.4 在你的例子中都失败了。
  • @Morwenn 那是无效的代码吗?
  • @mr5 实际上,std::queue 没有方法 begin()。当我告诉你它有效时,我将std::queue 混淆为std::deque。很抱歉。

标签: c++ c++11 queue


【解决方案1】:

嗯,答案实际上很简单:std::queue 中没有函数begin(),也没有std::begin 的任何过载std::queue。你可以看看documentation

核心问题是std::queue 不应该被迭代。它的存在是为了满足其他需求。如果你真的需要迭代它,你应该只使用支持迭代并且你的代码有效的底层容器(默认为std::deque)。

【讨论】:

  • 我仍在等待其他答案,但我认为没有比这更不同的答案了。如果它符合我的需要,我会寻找std::deque。感谢您的解释。
  • 注意std::queue只是一个适配器类,它“添加”了两个函数pushpop具有正确的含义。你也可以使用底层的std::deque,但是你没有这些便利的功能。但是你也可以声明一个std::deque一个std::queue;使用deque 进行迭代,使用queue 方便地推送和弹出。
  • 严格来说它并没有“添加”这两个函数,而是用这两个函数替换了整个容器接口。 std::queue 的目的几乎是防止用户访问底层容器,而不是按 FIFO 顺序。正式目的是实现一个简单的抽象数据类型,但它相当于接口缩小。也就是说queue存在的原因是为了防止用户对其进行迭代。如果您想将deque 用作FIFO 以及其他用途,只需将函数命名为push_backpop_front
【解决方案2】:

虽然std::queue 不支持迭代,但它确实有一个复制构造函数,它允许我们将队列的临时副本的内容传输到另一个支持迭代的临时容器(例如std::vectorstd::list,或者如果使用 C++11,std::forward_list)。

因此,虽然它确实需要一些运行时开销,并且如果目标是有一种合理方便的方法来迭代 std::queue 变量的值,那么它不如能够直接迭代结构那么好,您可以考虑使用如下模板化函数(将其添加到适当的头文件中):

#include <queue>
#include <list>

// returns an iterable copy of the given queue
template<class T> std::list<T> toList(std::queue<T> qCopy) {
    std::list<T> returnList;
    while (!qCopy.empty()) {
        returnList.push_back(qCopy.front());
        qCopy.pop();
    }
    return returnList;
}

并入 OP 的用例:

#include <iostream>
int main() {
    std::queue<int> Q;

    for (int i = 0;i < 10; ++i)
        Q.push(i);

    std::cout << "\nqueue contains: ";
    for (auto i : toList(Q))
        std::cout << i << ", ";

    return 0;
}

【讨论】:

    猜你喜欢
    • 2016-10-31
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    • 2014-12-06
    • 2019-03-07
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多