Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;映射,使用常量引用作为值类型,这里有什么问题?_C++_Reference_Stdmap - Fatal编程技术网

C++ C++;映射,使用常量引用作为值类型,这里有什么问题?

C++ C++;映射,使用常量引用作为值类型,这里有什么问题?,c++,reference,stdmap,C++,Reference,Stdmap,今天我看到了我老板的代码,它使用常量引用作为映射的值类型 代码如下: class ConfigManager{ public: map<PB::Point, const PB::WorldPoint&, compare_point> world_point; //the rest are omitted }; 但是如果我改变map我的map到映射myMap,它编译 又出现了另一个问题。使用map-myMap,我不能使用[]获取该对,但我可以使

今天我看到了我老板的代码,它使用常量引用作为
映射
的值类型

代码如下:

class ConfigManager{
    public:
        map<PB::Point, const PB::WorldPoint&, compare_point> world_point;
    //the rest are omitted
};
但是如果我改变
map我的map
映射myMap,它编译

又出现了另一个问题。使用
map-myMap
,我不能使用
[]
获取该对,但我可以使用
map.find()

(在我告诉老板使用
[]
无法编译后,老板让我使用
map.find()

代码示例2 如果我正确理解输出(如果我理解错误,请纠正我),则表明:

  • make\u pair(“爱”,a)
    创建对象
    pair
    。然后将这一对插入到
    myMap
  • 不知怎的,我不知道它是怎么发生的,一个
  • 临时副本立即被销毁。对我来说,这意味着一个
    临时副本的内存现在不属于任何人,如果我理解正确,它现在是一个可用的内存空间,可以用任何值填充
    
    所以现在我又感到困惑了

    我的问题是:

  • 代码示例3发生了什么变化?我的理解正确吗?为什么一个
  • 的临时副本在语句之后立即被销毁?使用常量引用是否可以延长临时变量的生命周期?我的意思是,我认为它在
    main
    完成之前不应该被破坏

  • 我老板的密码是不是不正确而且很危险

  • 为什么语句的临时副本会在语句之后立即被销毁

    因为(在大多数情况下)临时工就是这样工作的。在创建它们的语句结束之前,该语句将一直处于活动状态。在这种情况下,临时生存期的延长不适用,请参阅。TLDR版本是

    一般来说,临时文件的使用寿命不能通过以下方式进一步延长: “传递”:第二个引用,从引用到 临时绑定的,不影响其使用寿命

    我可以使用常量引用作为映射的值类型吗


    是的,只要您意识到向映射添加常量引用对所引用对象的生存期没有影响。您的BOSS代码也不正确,因为
    make\u pair
    返回的临时值在语句末尾被销毁。

    您可以使用
    std::unique\u ptr

    示例3的代码会发生什么变化?我的理解正确吗

    你的解释很贴切。由
    std::make\u pair
    返回的
    std::pair
    是临时对象。临时
    std::pair
    包含
    a
    的副本。在表达式末尾,该对被销毁,这也会销毁其元素,包括
    a
    的副本

    为什么语句的临时副本会在语句之后立即被销毁?使用常量引用是否可以延长临时变量的生命周期?我的意思是,我认为它不应该被破坏,直到主要完成

    这里的临时变量是
    std::make_pair
    的结果,它被用作成员函数
    insert
    的参数。此处适用的相关规则包括:

    每当引用绑定到临时对象或其子对象时,临时对象的生存期将延长以匹配引用的生存期,但以下情况除外:

    • [……]
    • 在包含该函数调用的完整表达式结束之前,函数调用中引用参数的临时绑定一直存在[…]
    • [……]

    包含函数调用的完整表达式是表达式
    myMap.insert(make_pair(1,a))
    这意味着
    std::make_pair
    结果的生存期在函数返回后结束,包括它包含的
    A
    。新的
    std::map
    元素将引用临时
    std::pair
    中的
    A
    ,它将在
    insert
    返回后变为悬空

    我老板的密码是不是不正确而且很危险


    是的,
    myMap
    包含悬空引用。

    如果问题太长,很抱歉。我已经尽力把它缩短。这让我相信你老板的代码并没有按预期的那样工作。地图引用的对象似乎与原始对象不同。底线应该是,即使它确实按预期工作,但它导致这一级别的研究的事实表明,无论如何都应该避免它。@FrançoisAndrieux是的,没有看太长的代码这会从提到
    std::ref
    @StoryTeller UnslanderMonica中受益,
    std::ref
    在这里可以做什么?@Rick-它可以用来创建一对,其中包含
    a
    的引用包装,而不是副本。因此,使用
    a
    (而不是悬挂)来初始化地图中的项目。对不起,我不明白您的答案。在这种情况下,哪一条规则适用于临时对象的生存期不会延长?如果您的答案可以更长,我们将不胜感激。我们的目标似乎是要有一个地图,它引用了地图之外存在的元素。我不确定这个答案是否是等效的。由于C++14中有
    std::make_unique
    在初始化
    std::unique_ptr
    s时替换
    new T
    。在典型的现代C++中,<>代码> new < /C++ >的唯一用例是现在的布局。在C++ 20中,对于操作符new的演绎有增强。如果目标是引用现有对象,则不会使用临时对象。原始指针最适合只用于观察者的解决方案。谢谢您的帮助。但我不是在寻找替代方案。我更想知道为什么。我想指出的是,它是
    std::pair
    ,而
    V
    恰好是一个参考类型,但
    map
    本身的
    value\u类型
    不是一个。不管怎样,我得到了
    struct A {
        int x = 3;
        int y = 4;
    };
    
    map<int, A&> myMap;
    
    int main() {
        A a;
        myMap.insert(make_pair(1, a));
    }
    
    struct A {
        int x = 3;
        int y = 4;
    };
    
    map<int, const A&> myMap;
    
    int main() {
        A a;
        myMap.insert(make_pair(1, a));
    
        //can't compile
        cout << myMap[1].x << " " << myMap[1].y << endl; 
        
        //can work
        //auto it = myMap.find(1);
        //cout << it->second.x << " " << it->second.y << endl;
    }
    
    #include <map>
    #include <iostream>
    #include <string>
    using namespace std;
    
    struct A {
        int x = 3;
        int y = 4;
        ~A(){
            cout << "~A():" << x << endl;
            x = 0;
            y = 0;
        }
    };
    
    map<string, const A&> myMap;
    
    int main() {
        A a;
        cout << a.x << " " << a.y << endl;
        myMap.insert(make_pair("love", a));
        a.x = 999;
        cout << "hello" << endl;
        auto s = myMap.find("love");
        cout << s->second.x << " " << s->second.y << endl;
    }
    
    3 4
    ~A():3
    hello
    0 0
    ~A():999
    
    using value_t=std:: unique_ptr<A>;
    std::map<int, value_t> myMap;
    myMap.emplace(1,new A);
    myMap[1]=new A{5,6};
    myMap[1]->x=7;