struct const_int { const int x = 1; };
int main(int argc, char **argv)
{
std::unordered_map<int, const_int> map0;
std::unordered_map<int, const_int> map1 { map0 }; // OK
map1 = map0; // Compile-time error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该代码在Visual C ++ 2017中有效,但在Visual C ++ 2019中失败,并出现编译错误:
14.23.27911\include\list(1210): error C2280: 'std::pair<_Kty,_Ty> &std::pair<_Kty,_Ty>::operator =(volatile const std::pair<_Kty,_Ty> &)': attempting to reference a deleted function
with
[
_Kty=int,
_Ty=const_int
]
Run Code Online (Sandbox Code Playgroud)
哪个编译器版本具有正确的实现,或者在这种情况下未定义行为?
Mof*_*ofX 17
从Visual Studio开发人员社区引用Billy Robert O'Neil III,这不是错误:
这不是错误。
unordered_map是一个可识别分配器的容器,并且可识别分配器的容器的分配操作需要是value_type可复制分配的(请参阅containers.allocatoraware),然后unord.req说,出于对无序容器中的需求的目的,请查看key_type和mapped_type代替。这恰好在Visual C ++的早期版本中起作用,因为在赋值操作期间构造
std::list了其中的std::unordered_map一个结构,用于释放所有节点,因此即使允许分配元素,我们也没有这样做。但这意味着向已经包含100个元素的列表中分配100个值将对分配器进行200次不必要的调用:释放所有100个旧节点,然后分配100个新节点。您观察到的行为更改是因为在VS2019 Update 2中,我们实现了优化以重用分配中已分配的节点。
除了@MofX的答案外,我还要在此处添加一些资源,这也是因为引用的文本包含无效链接。
从[unord.map] / 2(强调我的):
一个
unordered_map满足所有的容器的需求的无序关联容器,和的分配感知 容器。
这导致[container.requirements.general] / 16,对于表86中的赋值表达式,要求是(强调我的):
要求:T是CopyInsertable到X和CopyAssignable。
当然,在OP的例子中使用的类型struct const_int { const int x = 1; };是不复制分配(由于const和没有用户定义的赋值运算符),因此编译失败。
我希望这可以使它更清楚。
(免责声明:最初,我确信MSVC在此处存在错误,但事实证明我错了)
| 归档时间: |
|
| 查看次数: |
604 次 |
| 最近记录: |