Mat*_*zak 7 c++ stl language-lawyer
无序的设置键是只读的,所以为什么在这种情况下我可以擦除元素:
std::unordered_set<std::string> s;
s.emplace("sth");
s.erase("sth");
Run Code Online (Sandbox Code Playgroud)
而在这不是:
std::unordered_set<std::string const> s;
const std::string str("sth");
s.emplace(str);
s.erase(str);
Run Code Online (Sandbox Code Playgroud)
如果设置本身就是const它会有意义但是使用const键我不太明白.这个断言失败了:
static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, "");
Run Code Online (Sandbox Code Playgroud)
为什么会写那个断言的人,检查密钥是不是const?
编辑:
实际上,上面的代码编译得很好std::set.因为std::unordered_set,失败直接在实例化.重现的最小例子:
// define a customized hash ...
int main() { sizeof(std::unordered_set<int const>); }
Run Code Online (Sandbox Code Playgroud)
我认为您缺少的是 std::set 实际上分配了自己的字符串。因此,当您说 s.emplace("sth") 时,它会创建一个新的“sth”字符串,它不会使用您的字符串(它使用它来构造一个新字符串)。为什么这些新分配的字符串是 const ?因为你不应该直接修改它们,否则你会破坏集合。如果直接将“aaa”更改为“zzz”,则集合仍会认为“zzz”是集合中的第一个元素,位于“bbb”之前。
那么为什么会有这个断言呢?因为 std 没有 const 对象的分配器 - 所以当它尝试分配 const 对象时它将失败。VS2017 的错误更加明显:“C++ 标准禁止 const 元素的容器,因为分配器格式不正确。”
| 归档时间: |
|
| 查看次数: |
169 次 |
| 最近记录: |