https://mp.weixin.qq.com/s/PP9lSNlyyzIKCR4HTnSqFA
情况
vector<vector<int>> a;
a.push_back({1,2});可以
a.emplace_back({1,2});报错
分析
std::vector<T,Allocator>::emplace_back的签名有下面几种:
c++ template< class... Args > void emplace_back( Args&&... args );(since C++11, until C++17)
c++ template< class... Args > reference emplace_back( Args&&... args );(since C++17, until C++20)
c++ template< class... Args > constexpr reference emplace_back( Args&&... args ); (since C++20)
push_back和emplace_back一个特别大的区别在于实例化std::vector之后,push_back的参数是已知的,就是T; 而emplace_back的参数是未知的,需要从parameter pack中进行推导。
std::vector<T,Allocator>::emplace_back期望从{1, 2}中推断出参数类型,而{1,2}需要知道它构造的对象类型才能转化为std::initializer_list,否则就大括号括起来的初始化列表。
解决方法
emplace_back({1,2});
修改成emplace_back(1,2);
emplace_back({1,2})
修改为emplace_back<std::vector<int>>({1,2})
或者emplace_back(std::vector<int>{1,2})
- 把
emplace_back({1,2})
修改为emplace_back<std::initializer_list<int>>({1,2})
或者emplace_back(std::initializer_list<int>{1,2})
。
通过cppinsights可以看到修改后,编译器视角的代码变化