【问题标题】:C++: Is it possible to use a reference as the value in a map?C++:是否可以使用引用作为映射中的值?
【发布时间】:2010-11-21 17:44:11
【问题描述】:

是否可以在 C++ 的标准地图容器中使用引用作为值?
如果没有 - 为什么不呢?

示例声明:

map<int, SomeStruct&> map_num_to_struct;

示例用法:

...
SomeStruct* some_struct = new SomeStruct();
map_num_to_struct[3] = *some_struct;
map_num_to_struct[3].some_field = 14.3;
cout<<some_struct.some_field;
...

我希望看到 14.3 被打印出来......

【问题讨论】:

标签: c++ reference map


【解决方案1】:

我相信这是可能的,但有限制。由于在稍后阶段无法分配引用,因此您将无法在地图上调用 operator[]。但是,您可以调用各种其他成员函数。只要您不违反任何参考规则。例如:

// You need the instances to exist before
auto a1 = SomeStruct();
auto a2 = SomeStruct();
auto a3 = SomeStruct();

// Creating the map with an initializer list.
std::map<int, SomeStruct&> map_num_to_struct = {
    { 1, a1 },
    { 2, a2 },
    { 5, a3 }
};

// The following won't work because operator[] returns
// a reference to the value, which can't be re-assigned.
// map_num_to_struct[6] = a1;

// These will work.
map_num_to_struct.insert({6, a1});
map_num_to_struct.insert(std::pair<int, SomeStruct&>(7, a1));

// Iterating through the map.
for (auto &a: map_num_to_struct) {
    cout << a.first << ": " << a.second.some_field << endl;
}

// We can't use operator[] for indexing.
// map_num_to_struct[5].do_something();
auto a_iter = map_num_to_struct.find(5);
if (a_iter != map_num_to_struct.end()) {
    cout << a_iter->first << ": " << a_iter->second.some_field << endl;
    a_iter->second.some_field = 14.3;
    cout << a_iter->first << ": " << a_iter->second.some_field << endl;
}

我不知道较新的 C++ 标准是否使这成为可能,但它至少适用于 GCC 和 clang。

【讨论】:

    【解决方案2】:

    不,不是。不过,您可以使用指针作为值类型。

    【讨论】:

      【解决方案3】:

      没有。 STL 容器值类型需要可赋值。参考是不可分配的。 (您不能为它们分配不同的对象来引用。)

      【讨论】:

      • 从什么时候开始需要分配容器值类型?它们需要是可复制的。参考确实不是“可复制的”,但您的答案在技术上是错误的。我错过了什么?
      【解决方案4】:

      不,您不能使用引用,但可以使用指针。在您的示例中,您似乎混淆了两者。试试:

      map<int, SomeStruct *> map_num_to_struct;
      SomeStruct* some_struct = new SomeStruct();
      map_num_to_struct[3] = some_struct;
      map_num_to_struct[3]->some_field = 14.3;
      cout<<some_struct->some_field;
      

      【讨论】:

        【解决方案5】:

        我不这么认为,如果我没记错的话,引用应该被视为指向某个元素的常量指针。但是你可以只使用指向相同效果的指针。

        【讨论】:

        • 取消引用你所有的迭代器值并不好玩:(
        • 但是你可以使用 -> 而不是 .而且看起来更酷(这绝对是使用指针的正当理由)
        • @GWW,没问题 - 您可以使用 boost::inderect_iterator 获得“自动取消引用”。
        • @Kirill 这实际上非常有用。我需要停止懒惰并开始更频繁地查看提升。我已经将它用于一堆东西。 @Dasuraga 如果您使用矢量而不是地图,它会变得丑陋(*it)-&gt;do_something(); 不是那么酷
        【解决方案6】:

        值类型必须是可赋值的,而引用不是。

        无论如何你都可以使用 tr1 reference_wrapper

        【讨论】:

        • OP 谈论的是值类型,而不是键类型。不过你说得对。
        猜你喜欢
        • 2017-02-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-16
        • 1970-01-01
        • 2013-12-29
        • 2011-11-30
        相关资源
        最近更新 更多