提问人:BulGali 提问时间:7/16/2020 最后编辑:BulGali 更新时间:7/16/2020 访问量:112
将非临时对象传递给 const 字符串引用仍然会打印垃圾
Passing non-temporary object to const string reference still prints garbage
问:
我试图自己为my_vec编写一个迭代器:
#define BEGIN true
#define END false
#include <vector>
#include <iostream>
template<typename Container>
class my_vec {
private:
class iterator {
const my_vec *this_vec;
using iterator_type = typename std::vector<std::pair<int, const Container&>>::const_iterator;
iterator_type itr;
public:
iterator(const my_vec &s, bool state) :
this_vec(&s) {
if (state == BEGIN) {
itr = s.v.begin();
} else { /*(state==END)*/
itr = s.v.end();
}
}
iterator& operator++() {
itr++;
return *this;
}
std::pair<int, const Container&> operator*() const {
return std::make_pair(1, this_vec->dog);
}
bool operator!=(iterator other) const {
return itr != other.itr;
}
}
;
public:
std::string dog = "DOG";
std::vector<std::pair<int, Container>> v;
my_vec(int space) {
v.reserve(space);
}
iterator begin() const {
return iterator(*this, BEGIN);
}
iterator end() const {
return iterator(*this, END);
}
}
;
但是,在运行以下 main.cpp 时:
#include "my_vec.h"
int main() {
my_vec<std::string> t(6);
t.v.emplace_back(std::make_pair(1, "HELLO"));
t.v.emplace_back(std::make_pair(2, "BYE"));
t.v.emplace_back(std::make_pair(3, "CAT"));
for (const auto &pair : t) {
std::cout << pair.first << std::endl;
std::cout << pair.second << std::endl;
}
return EXIT_SUCCESS;
}
预期输出为:
1
DOG
1
DOG
1
DOG
但是,实际输出为:
1
然后程序停止或打印垃圾。
似乎问题出在这个函数上:
std::pair<int, const Container&> operator*() const {
return std::make_pair(1, this_vec->dog);
}
为什么会发生这种行为,因为“狗”不是局部变量?
另外,如何在不更改运算符*的函数定义的情况下修复它?
答:
5赞
Igor Tandetnik
7/16/2020
#1
std::make_pair(1, this_vec->dog)
返回一个 类型的临时(我们给它起个名字) 。然后,类型的返回值(我们将其命名为 )构造自 ,从而绑定到 。最后,临时文件被销毁并返回给呼叫者,并持有悬空的引用。尝试使用此返回值时会表现出未定义的行为。t
std::pair<int, std::string>
r
std::pair<int, const std::string&>
t
r.second
t.second
t
r
来得及
return {1, this_vec->dog};
这将直接构造返回值,而无需中间临时对。
评论
v
t.v.emplace_back(std::make_pair(1, "HELLO"));
v
#define BEGIN true
避免不必要的混淆,例如。