3

我发现了 std::reference_wrapper 提供的好工具,但这种行为对我来说听起来很奇怪。

#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <vector>
#include <numeric>
int main()
{
    std::vector<int> vectorA(10);
    std::vector<std::reference_wrapper<int>> vec;
    std::iota(vectorA.begin(),vectorA.end(),0);

    for(auto i: vectorA){
        std::cout << "In vectorA: "<<  i << " ";
    }
    std::cout << "\n";

    for(unsigned i=0; i< vectorA.size(); i++){
        vec.push_back(std::ref(vectorA[i]));
    }

    for(auto i: vec){
        std::cout << "In vec: "<<  i << " ";
    }
    std::cout << "\n";

    vectorA.erase(vectorA.begin()+9);

    for(auto i: vectorA){
        std::cout << "In vectorA: "<<  i << " ";
    }
    std::cout << "\n";


    for(auto i: vec){
        std::cout << "In vec: "<<  i << " ";
    }
    std::cout << "\n";

}

为什么擦除vec ( vectorA[9] ) 中引用的元素不会影响向量vec的大小?此外,为什么vec[9]仍然可以访问?

4

1 回答 1

3

std::reference_wrapper存储对对象的引用。它不会以任何方式影响被引用对象的生命周期,并且您承诺std::reference_wrapper在被引用对象被销毁后不会尝试使用。这样做的惩罚是未定义的行为

因此,当您从 中删除引用的元素时vectorA,其中的引用包装器vec现在无效,但它不知道,您也无法判断。现在,对该引用包装对象的任何使用都将导致未定义的行为。

未定义行为的一个可能后果是您的程序继续运行,这就是这里发生的情况。您尝试使用无效的引用包装对象,并返回一个值,但这并不意味着程序有效。

于 2020-01-24T11:45:24.680 回答