簡體   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