将非临时对象传递给常量字符串引用仍然打印垃圾
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);
}
为什么会出现这种行为,因为 'dog' 不是局部变量?
还有,在不改变operator*的函数定义的情况下如何修复?
std::make_pair(1, this_vec->dog)
return 类型为 std::pair<int, std::string>
的临时文件(我们将其命名为 t
)。然后 std::pair<int, const std::string&>
类型的 return 值(我们将其命名为 r
)是从 t
构造的,其中 r.second
绑定到 t.second
。最后,临时 t
被销毁并且 r
被 returned 给调用者,持有悬空引用。尝试使用此 return 值会出现未定义的行为。
成功
return {1, this_vec->dog};
这直接构造了 return 值,没有中间临时对。
我试图自己为 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);
}
为什么会出现这种行为,因为 'dog' 不是局部变量?
还有,在不改变operator*的函数定义的情况下如何修复?
std::make_pair(1, this_vec->dog)
return 类型为 std::pair<int, std::string>
的临时文件(我们将其命名为 t
)。然后 std::pair<int, const std::string&>
类型的 return 值(我们将其命名为 r
)是从 t
构造的,其中 r.second
绑定到 t.second
。最后,临时 t
被销毁并且 r
被 returned 给调用者,持有悬空引用。尝试使用此 return 值会出现未定义的行为。
成功
return {1, this_vec->dog};
这直接构造了 return 值,没有中间临时对。