[英]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.