vector<vector<int> > res;
res.emplace_back({1,2}); // change to res.push_back({1,2}); would work
Run Code Online (Sandbox Code Playgroud)
这给了我错误
main.cpp:61:25: error: no matching function for call to ‘std::vector<std::vector<int> >::emplace_back(<brace-enclosed initializer list>)’
main.cpp:61:25: note: candidate is:
In file included from /usr/include/c++/4.7/vector:70:0,
from /usr/include/c++/4.7/bits/random.h:34,
from /usr/include/c++/4.7/random:50,
from /usr/include/c++/4.7/bits/stl_algo.h:67,
from /usr/include/c++/4.7/algorithm:63,
from miscalgoc.hpp:1,
from main.cpp:1:
/usr/include/c++/4.7/bits/vector.tcc:92:7: note: void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {}; _Tp = std::vector<int>; _Alloc = std::allocator<std::vector<int> >]
Run Code Online (Sandbox Code Playgroud)
如何使这项工作?另外,为什么这里需要分配器?
Mar*_*cia 23
问题是函数模板参数不会std::initializer_list从braced-init-list(如{ 1, 2 })中推断出来.
例:
#include <initializer_list>
#include <type_traits>
template<typename T>
void func(T arg) {
}
int main() {
auto init_list = {1, 2}; // This works because of a special rule
static_assert(std::is_same<decltype(init_list), std::initializer_list<int>>::value, "not same");
func(std::initializer_list<int>{1, 2}); // Ok. Has explicit type.
func({1, 2}); // This doesn't because there's no rule for function
// template argument to deduce std::initializer_list
// in this form.
}
Run Code Online (Sandbox Code Playgroud)
std::vector::emplace_back()是一个函数模板,其参数是推导出来的.所以传递它是{1, 2}行不通的,因为它无法推断它.为它添加一个显式类型
res.emplace_back(std::initializer_list<int>{1,2});
Run Code Online (Sandbox Code Playgroud)
会让它发挥作用.
@Mark的回答非常正确。现在让我们考虑一个更实际的案例。经过一些正确的操作后,您已经使用 收集了一些数据vector<int>,并且想将其推入vector<vector<int>>:
std::vector<std::vector<int>> res;
for (int i = 0; i < 10000; ++i) {
//
// do something
//
std::vector<int> v(10000, 0); // data acquired
res.push_back(v);
}
Run Code Online (Sandbox Code Playgroud)
这不像分配您已经知道的值。利用std::initializer_list可能不再是一个解决方案。在这种情况下,您可以使用std::move(与emplace_back或push_back一起使用)
for (int i = 0; i < 10000; ++i) {
std::vector<int> v(10000, 0); // will become empty afterward
res.emplace_back(std::move(v)); // can be replaced by
// res.push_back(std::move(v));
}
Run Code Online (Sandbox Code Playgroud)
性能或多或少有所提高。您仍然可以从xvalue移动插入的概念中受益,通过移动构造函数而不是复制来构造对象。
更新
之所以有效,res.push_back(move(v))是因为它们在 C++11 之后重载了该方法std::vector::push_back(value_type&& val)。它是故意支持右值引用的。
| 归档时间: |
|
| 查看次数: |
6163 次 |
| 最近记录: |