为什么不允许使用此参考集?

时间:2018-09-02 17:55:50

标签: c++

C ++的新手,我想如果我定义一个容器并将其类型指定为string,那么它应该从string中出来而不必大惊小怪,我想拥有一个引用变量别名这个字符串。显然,我在这里错过了一些东西,因为编译器抱怨它无法将void转换为字符串。有人可以帮忙澄清一下吗?谢谢。

#include <queue>
#include <string>
#include <iostream>

using namespace std;


int main(int argc, char** argv) {
    std::queue<std::string> myqueue;

    myqueue.push("val1");
    myqueue.push("val2");

    while (!myqueue.empty()) {
        std::string & s = myqueue.pop();
        std::cout << s << endl;
    }
}

4 个答案:

答案 0 :(得分:4)

那是因为std::queue::pop没有返回任何内容(无效)。

如果要访问第一个元素然后将其删除,则应使用std::queue::front,然后使用std::queue::pop

while (!myqueue.empty()) {
  std::string & s = myqueue.front();
  std::cout << s << endl;
  myqueue.pop();
}

我将myqueue.pop();移到了std::cout << s << endl;之后,以避免悬挂引用(对不再存在的对象的引用)。

答案 1 :(得分:3)

master的返回类型为queue::pop,仅删除第一个元素。如果要保留其值,请首先使用void对其进行检索,并应按值而不是按引用保留它,因为它弹出时,对其的引用就变得悬而未决。

front()

答案 2 :(得分:1)

std::queue::pop()不返回任何内容。它只是删除队列的第一个元素。您必须使用std::queue::front()获取对第一个元素的引用(并将其存储在s中),然后调用std::queue::pop()从队列中的之后您已经使用过s,而您不再需要它。

在调用s之后不要使用存储在std::queue::pop()中的引用,这很重要,因为在后台,std::queue包装了一个std::dequeue对象和{{1} }在其上调用std::dequeue::pop_first()std::queue::pop()的文档页面指出:

  

迭代器和对已擦除元素的引用均无效。

您的代码可能是:

std::dequeue::pop_first()

答案 3 :(得分:0)

将元素从队列中移出并立即调用pop()

在使用队列中的元素时,而不是:

  • 从队列中存储对您将要pop()的元素的引用,或者
  • front()复制元素,以避免悬而未决的参考场景,

您可以front()元素移出队列,并立即在队列中调用pop()。例如

#include <iostream>
#include <queue>
#include <string>
#include <utility>

template<typename T>
T removeFrontFromOfQueue(std::queue<T>& q) {
    T front = std::move(q.front());
    q.pop();
    return front;  // Should be able to rely on NRVO, and if not, a move ctor.
}

int main() {
    std::queue<std::string> myqueue({"val1", "val2"});

    while (!myqueue.empty()) {
        std::string s = removeFrontFromOfQueue(myqueue);
        std::cout << s << " ";
    }  // val1 val2
}

如以下问答所述,

这很安全。


限制对front()对象的引用的生存期

或者,如果您选择存储对队列front()的引用,请考虑在队列上调用pop()之前限制引用的生存期。例如:

while (!myqueue.empty()) {
    {
        const std::string& s = myqueue.front();
        std::cout << s << " ";
    }
    myqueue.pop();
} // val1 val2