将非临时对象传递给常量字符串引用仍然打印垃圾

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 值,没有中间临时对。