C++报错原因汇总 Q1:为什么error: 'class std::queue<Person>' has no member named 'pop_back?
问题
#include <queue>
#include <string>
#include <stack>
#include <iostream>
using namespace std;
class Person {
public:
Person():m_name("null"), m_age(-1){}
Person(string name, int age):m_name(name), m_age(age) {}
string m_name;
int m_age;
};
//person对象的<< 运算符重载
ostream& operator << (ostream &out, Person &p) {
out << "姓名:" << p.m_name << "\t年龄:" << p.m_age;
return out;
}
void MyPrint(queue<Person> &t) {
int temp_num = t.size();
for(int i = 0; i < temp_num; i++) {
cout << t.front() << endl; //不能是back()
t.pop(); //从队头删除一个元素
}
}
void MyPrint(stack<Person, queue<Person>> &t) {
int temp_num = t.size();
for(int i = 0; i < temp_num; i++) {
cout << t.top() << endl;
t.pop();
}
}
// error: 'class std::queue<Person>' has no member named 'pop_back' c.pop_back();
// 明白为什么错了,因为stack因为queue没有pop_back(),所以这样 stack<Person, queue<Person> > s(q); 构造是错误的
// 但是构造过程没问题,操作时就会出问题,vector和deque有pop_back(),所以可以用他们俩来拷贝构造stack
void test() {
//创建4个person对象
string name_arr[] = {"小王", "小米", "苹果", "校长"};
int age_arr[] = {18, 12, 1, 88};
const int person_num = sizeof(name_arr) / sizeof(name_arr[0]); //person数组的大小为常量
Person p[person_num];
//存入queue
queue<Person> q;
for(int i = 0; i < person_num; i++) {
p[i] = Person(name_arr[i], age_arr[i]); //匿名对象,赋值
q.push(p[i]);
}
//构造一个stack
stack<Person, queue<Person> > s(q);
//打印
MyPrint(q);
cout << endl;
MyPrint(s);
}
int main() {
test();
return 0;
}

queue确实没有pop_back()成员函数,而且代码中也没有用到pop_back(),为什么还会出现“queue没有pop_back()成员函数”这种提示呢?
原因
通过注释部分代码,找到问题所在之处,错误代码在line31:37
void MyPrint(stack<Person, queue<Person>> &t) {
int temp_num = t.size();
for(int i = 0; i < temp_num; i++) {
cout << t.top() << endl;
t.pop();
}
}
下面这一行也通过了编译器
stack<Person, queue<Person> > s(q);
通过回想,想到有一次看到用其他容器拷贝构造stack时,好像作者只写了deque和vector
ref: http://www.cplusplus.com/reference/stack/stack/stack/
--------------
// constructing stacks
#include <iostream> // std::cout
#include <stack> // std::stack
#include <vector> // std::vector
#include <deque> // std::deque
int main ()
{
std::deque<int> mydeque (3,100); // deque with 3 elements
std::vector<int> myvector (2,200); // vector with 2 elements
std::stack<int> first; // empty stack
std::stack<int> second (mydeque); // stack initialized to copy of deque
std::stack<int,std::vector<int> > third; // empty stack using vector
std::stack<int,std::vector<int> > fourth (myvector);
std::cout << "size of first: " << first.size() << '\n';
std::cout << "size of second: " << second.size() << '\n';
std::cout << "size of third: " << third.size() << '\n';
std::cout << "size of fourth: " << fourth.size() << '\n';
return 0;
}
通过查看stack首页的一句话,找到最终的原因

stacks are implemented as container adaptors, which are classes that use an encapsulated object of a specific container class as its underlying container, providing a specific set of member functions to access its elements. Elements are pushed/popped from the “back” of the specific container, which is known as the top of the stack.
The underlying container may be any of the standard container class templates or some other specifically designed container class. The container shall support the following operations:
- empty
- size
- back
- push_back
- pop_back
The standard container classes vector, deque and list fulfill these requirements. By default, if no container class is specified for a particular stack class instantiation, the standard container deque is used.
这里说那些可以构造出stack的容器必须具备这些方法
- empty
- size
- back
- push_back
- pop_back
满足这些条件的标准容器只有vector、deque、list,相应的,一开始就默认使用deque构造stack。
所以我们平时写的
stack<int>其实是stack<int, deque<int> >
stack的构造函数可能是这样的:stack<T1, T2 = deque <T1> >
所以,我们也可以指定其他容器来构造stack
比如,stack<int, list<int> >
最后,也不难理解为什么会有 error: 'class std::queue<Person>' has no member named 'pop_back'
这句话了。因为queue没有pop_back,所以不够格,也就不能进行pop()操作。
所以,stack在进行push和pop时,实际上使用的是deque的push_back,pop_back。
stack 的empty和top也对应于deque的empty和back 。stack 准确的说,不是一个container,而是一个adapter,它改写了deque的接口。
也就是说,stack就是一个披着stack皮的deque,就是一个堵住deque头,只对deque的尾部进行操作的东东。
也可以参考<<STL源码剖析>> P167 4.5.2

该博客分析了C++编程时遇到的`error: ‘class std::queue<Person>‘ has no member named ‘pop_back’`错误。错误源于尝试对std::queue使用pop_back方法,但实际上该方法不属于std::queue。std::queue是一个容器适配器,其底层容器默认为std::deque,只支持push_back和pop_front操作。因此,应该使用pop_front而非pop_back来移除队列首元素。

被折叠的 条评论
为什么被折叠?



