c++ - 为什么在返回 unordered_map 值时需要声明默认构造函数才能编译?
问题描述
除非我取消注释默认构造函数声明,否则此示例无法编译:
#include<unordered_map>
#include <iostream>
struct foo{
int data;
/*foo(){
data = 0;
std::cout << "DEFAULT\n";
}*/
foo(int d){
data = d;
std::cout << "PARAM\n";
}
};
struct bar{
std::unordered_map<int, foo> map;
foo getElem(int i){
return map[i];
}
};
int main() {
bar b;
foo f1(1);
foo f2(2);
b.map.insert({1,f1});
b.map.insert({2,f2});
foo f3 = b.getElem(1);
}
/opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/tuple:1689:70: error: no matching function for call to 'foo::foo()'
1689 | second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
| ^
当我取消注释默认构造函数声明并成功编译时,面包屑显示从未调用过默认构造函数。
这里发生了什么?类似的问题是由于最令人烦恼的 parse,但没有任何显式的构造函数调用,我不确定这里是否是这种情况。
这个答案提供了关于为什么 unordered_map 会隐式调用默认构造函数的提示。问题是所描述的记录行为和 MVP 的某种组合吗?
解决方案
当编译器编译这一行时:
foo f3 = b.getElem(1);
1
作为参数传递给函数(除非发生了很多优化魔法,这是不能保证的)。此函数无法知道1
永远不会丢失密钥。因此,调用在映射中分配条目的代码。如果缺少密钥,则传递给此代码的内容是什么?是的,一个默认构造的foo
.
所以,简而言之,你知道
从未调用过默认构造函数
但编译器和链接器没有。
推荐阅读
- interface - 如何更改我正在使用 App Designer for the Unified Interface 开发的 App 的唯一名称中的提供程序部分?
- java - 使用 webtable 迭代下拉列表时无法执行 IndexOutOfBounds 异常
- mongodb - mongodb查询获取未检查的打印机?
- python - 从列表 Python 中删除匹配项
- python - 如何将 sts.LinearRegression 替换为 Tensorflow 概率结构化时间序列模型组件的非线性模型
- android - 从哪里获取订阅 ID
- javascript - 托管到 vps 时所有 javascript 上的非法字符错误
- github - github.io 和 github-pages 之间的冲突
- rxjs - RxJS:当源之间的延迟发射太长时发射值
- android - 高级 recyclerview 适配器