【问题标题】:Why deleting the referenced value by an element of a vector<reference_wrapper<T>> does not invalidate the vector?为什么通过 vector<reference_wrapper<T>> 的元素删除引用的值不会使向量无效?
【发布时间】:2020-05-10 17:37:59
【问题描述】:

我发现了 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] 仍然可以访问?

【问题讨论】:

  • this behaviour sounds weird to me 此行为未定义。 :) C++ 不能防止愚蠢的事情发生。
  • 因为您有责任确保被引用的对象比引用更有效。你会得到与指针或普通引用相同的行为。这就是c++ 的工作方式。没有你的要求,它不会为你神奇地做事。

标签: c++ reference std reference-wrapper


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    • 2021-06-18
    • 2016-03-31
    • 2021-08-29
    • 1970-01-01
    相关资源
    最近更新 更多