[英]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;
constMap
和moreConstMap
之間有什么權衡或區別?
答案也可能適用於其他 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/emplace
和erase
來修改 map。
您應該對
std::map
應用多少const
?
很少:任何。 您通常map
限制在class
中,並且僅通過成員函數公開它。
constMap 和 moreConstMap 之間有什么權衡或區別?
這取決於constMap
和moreConstMap
真正含義。 它們沒有標准化。 標准const
可能使編譯器的優化部分可以做出假設以排除代碼中實際上能夠更改變量的某些分支。 不需要處理這些分支可能會使程序更快一些。
除了它們是不同的類型之外, std::map
的情況沒有區別。
由於變量聲明為const
,因此無法更改 map class 的 state 本身。
只有您可以調用的成員函數是 const 限定的成員函數,例如const_iterator find( const Key& key ) const;
在constConfigMap
和const 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::pair
的second
成員未聲明為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.