繁体   English   中英

使用 std::map 的 const 正确性

[英]Const correctness with a std::map

您应该对std::map应用多少const

// Given a custom structure, really any type though
struct Foo
{
   int data;
};

// What's the difference between these declarations?
const std::map<int, Foo> constMap;
const std::map<const int, const Foo> moreConstMap;

constMapmoreConstMap之间有什么权衡或区别?

答案也可能适用于其他 stl 容器。

编辑1

提供更多上下文。 考虑两者之间差异的一个潜在用例可能是范围为 a.cpp 文件的 static 查找表。 比方说...

//Foo.cpp
namespace {
   const std::map<int, Foo> constConfigMap{ {1, Foo{1}}, {2, Foo{2}} };
   // vs
   const std::map<const int, const Foo> moreConstConfigMap{ {1, Foo{1}}, {2, Foo{2}} };
}

void someFunctionDefinition()
{
   Foo blah { constConfigMap.at(2) };

   // do something with blah
}

std::map包含pair {key, value} key始终是不变的,你不能修改它。 另一方面, value是可修改的,如果您使用const ,则不是。 因为一开始的那些const ,任何东西都是可以修改的,所以你的问题的答案是它们是完全一样的。 没有区别。

如前所述,map 中的键是隐式常量。

将值设为 const 类型将阻止您使用mymap[k] = v ,因为索引运算符将返回对 const 的引用。 您需要使用insert/emplaceerase来修改 map。

您应该对std::map应用多少const

很少:任何。 您通常map限制在class中,并且仅通过成员函数公开它。

constMap 和 moreConstMap 之间有什么权衡或区别?

这取决于constMapmoreConstMap真正含义。 它们没有标准化。 标准const可能使编译器的优化部分可以做出假设以排除代码中实际上能够更改变量的某些分支。 不需要处理这些分支可能会使程序更快一些。

除了它们是不同的类型之外, std::map的情况没有区别。

  • 由于变量声明为const ,因此无法更改 map class 的 state 本身。

  • 只有您可以调用的成员函数是 const 限定的成员函数,例如const_iterator find( const Key& key ) const;

constConfigMapconst std::pair<const int, const Foo>的情况下,两个 const 限定的find()都将返回一个const_iterator引用const std::pair<const int, Foo>类型的 object(就像operator[]一样) const std::pair<const int, const Foo>moreConstConfigMap的情况下。 这些类型几乎是同义词,因为std::pairsecond成员未声明为mutable 这些是不同的类型,因为它们是由不同的词位声明的,可以通过以下代码说明:

struct Foo
{
   int data;
   void bar() {}
   // needs to be const-qualified
   bool operator==(const Foo& other) const { return data == other.data; }
};

namespace {
   const std::map<int, Foo> constConfigMap{ {1, Foo{1}}, {2, Foo{2}} };
   // vs
   const std::map<const int, const Foo> moreConstConfigMap{ {1, Foo{1}}, {2, Foo{2}} };
}

int main() {
    auto it1 = constConfigMap.find(1);
    auto it2 = moreConstConfigMap.find(1);
    *it1 == *it2; //  error: no match for ‘operator==’
    it1->second == it2->second;
    it1->second.bar();  // error: passing ‘const Foo’ as ‘this’ argument discards qualifiers

    // neither is ill-formed, what would happen is other question
    const_cast<Foo&>(it1->second).bar(); 
    const_cast<Foo&>(it2->second).bar();
    return 0;
}

编译器会指出这些是不同的类型。

      |     *it1 == *it2;
      |     ~~~~ ^~ ~~~~
      |     |       |
      |     |       pair<[...],const Foo>
      |     pair<[...],Foo>

您根本无法更改 map 或其元素。 您不能在Foo的实例上调用非 const 限定成员而不丢弃const

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM