奇数 std::vector::emplace() 编译错误
Odd std::vector::emplace() compilation error
我在使用 std::vector::emplace()
和 std::vector::emplace_back()
时遇到了一个奇怪的编译器错误:
#include <vector>
struct Foo {
int bar;
Foo(int _bar) : bar(_bar) { }
};
int main() {
// Declaration 1
std::vector<Foo> vec(10);
// Declaration 2
// std::vector<Foo> vec{};
vec.emplace_back(1);
return 0;
}
当我 compile 执行此操作时,出现以下错误:
In file included from /usr/include/c++/6/vector:62:0,
from prog.cpp:2:
/usr/include/c++/6/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = Foo; _Args = {}]’:
/usr/include/c++/6/bits/stl_uninitialized.h:519:18: required from ‘static _ForwardIterator std::__uninitialized_default_n_1<_TrivialValueType>::__uninit_default_n(_ForwardIterator, _Size) [with _ForwardIterator = Foo*; _Size = long unsigned int; bool _TrivialValueType = false]’
/usr/include/c++/6/bits/stl_uninitialized.h:575:20: required from ‘_ForwardIterator std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator = Foo*; _Size = long unsigned int]’
/usr/include/c++/6/bits/stl_uninitialized.h:637:44: required from ‘_ForwardIterator std::__uninitialized_default_n_a(_ForwardIterator, _Size, std::allocator<_Tp>&) [with _ForwardIterator = Foo*; _Size = long unsigned int; _Tp = Foo]’
/usr/include/c++/6/bits/stl_vector.h:1309:36: required from ‘void std::vector<_Tp, _Alloc>::_M_default_initialize(std::vector<_Tp, _Alloc>::size_type) [with _Tp = Foo; _Alloc = std::allocator<Foo>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’
/usr/include/c++/6/bits/stl_vector.h:281:30: required from ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const allocator_type&) [with _Tp = Foo; _Alloc = std::allocator<Foo>; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<Foo>]’
prog.cpp:11:25: required from here
/usr/include/c++/6/bits/stl_construct.h:75:7: error: no matching function for call to ‘Foo::Foo()’
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
prog.cpp:7:2: note: candidate: Foo::Foo(int)
Foo(int _bar) : bar(_bar) { }
^~~
prog.cpp:7:2: note: candidate expects 1 argument, 0 provided
prog.cpp:4:8: note: candidate: constexpr Foo::Foo(const Foo&)
struct Foo {
^~~
prog.cpp:4:8: note: candidate expects 1 argument, 0 provided
prog.cpp:4:8: note: candidate: constexpr Foo::Foo(Foo&&)
prog.cpp:4:8: note: candidate expects 1 argument, 0 provided
但是,如果我注释掉声明 1 并改为使用声明 2,则代码可以正常编译。这是怎么回事?
您的问题不在于 vec.emplace_back(1);
。由于 std::vector<Foo> vec(10);
,您收到编译错误。该行试图创建一个包含 10 个默认构造元素的向量。由于您的 class 没有默认构造函数,因此您无法创建 10 个默认元素。
要使其正常工作,您需要提供 class 它可以复制到向量中的实例。看起来像
std::vector<Foo> vec(10, Foo(whatever_number_you_want));
或者您可以只添加默认构造函数。
std::vector<Foo> vec{};
不会给您带来任何问题,因为它不会尝试默认构造任何元素。空构造函数 returns 一个大小为 0 的向量,这意味着没有构造任何对象,从而避免了您未定义的默认构造函数。
原因是 std::vector<Foo> vec(10)
将实例化一个包含 10 个 "empty" Foo 对象的向量,即需要默认构造函数的 class Foo
的实例叫。但是,您的 class Foo
不提供默认构造函数。
第二条语句 std::vector<Foo> vec{}
实例化了一个空向量,因此没有实例化 Foo
-object(这需要默认构造函数)。
要解决您的问题,请在 Foo
:
中定义默认构造函数
struct Foo {
int bar;
Foo() : bar(0) {};
Foo(int _bar) : bar(_bar) { };
};
我在使用 std::vector::emplace()
和 std::vector::emplace_back()
时遇到了一个奇怪的编译器错误:
#include <vector>
struct Foo {
int bar;
Foo(int _bar) : bar(_bar) { }
};
int main() {
// Declaration 1
std::vector<Foo> vec(10);
// Declaration 2
// std::vector<Foo> vec{};
vec.emplace_back(1);
return 0;
}
当我 compile 执行此操作时,出现以下错误:
In file included from /usr/include/c++/6/vector:62:0,
from prog.cpp:2:
/usr/include/c++/6/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = Foo; _Args = {}]’:
/usr/include/c++/6/bits/stl_uninitialized.h:519:18: required from ‘static _ForwardIterator std::__uninitialized_default_n_1<_TrivialValueType>::__uninit_default_n(_ForwardIterator, _Size) [with _ForwardIterator = Foo*; _Size = long unsigned int; bool _TrivialValueType = false]’
/usr/include/c++/6/bits/stl_uninitialized.h:575:20: required from ‘_ForwardIterator std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator = Foo*; _Size = long unsigned int]’
/usr/include/c++/6/bits/stl_uninitialized.h:637:44: required from ‘_ForwardIterator std::__uninitialized_default_n_a(_ForwardIterator, _Size, std::allocator<_Tp>&) [with _ForwardIterator = Foo*; _Size = long unsigned int; _Tp = Foo]’
/usr/include/c++/6/bits/stl_vector.h:1309:36: required from ‘void std::vector<_Tp, _Alloc>::_M_default_initialize(std::vector<_Tp, _Alloc>::size_type) [with _Tp = Foo; _Alloc = std::allocator<Foo>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’
/usr/include/c++/6/bits/stl_vector.h:281:30: required from ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const allocator_type&) [with _Tp = Foo; _Alloc = std::allocator<Foo>; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<Foo>]’
prog.cpp:11:25: required from here
/usr/include/c++/6/bits/stl_construct.h:75:7: error: no matching function for call to ‘Foo::Foo()’
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
prog.cpp:7:2: note: candidate: Foo::Foo(int)
Foo(int _bar) : bar(_bar) { }
^~~
prog.cpp:7:2: note: candidate expects 1 argument, 0 provided
prog.cpp:4:8: note: candidate: constexpr Foo::Foo(const Foo&)
struct Foo {
^~~
prog.cpp:4:8: note: candidate expects 1 argument, 0 provided
prog.cpp:4:8: note: candidate: constexpr Foo::Foo(Foo&&)
prog.cpp:4:8: note: candidate expects 1 argument, 0 provided
但是,如果我注释掉声明 1 并改为使用声明 2,则代码可以正常编译。这是怎么回事?
您的问题不在于 vec.emplace_back(1);
。由于 std::vector<Foo> vec(10);
,您收到编译错误。该行试图创建一个包含 10 个默认构造元素的向量。由于您的 class 没有默认构造函数,因此您无法创建 10 个默认元素。
要使其正常工作,您需要提供 class 它可以复制到向量中的实例。看起来像
std::vector<Foo> vec(10, Foo(whatever_number_you_want));
或者您可以只添加默认构造函数。
std::vector<Foo> vec{};
不会给您带来任何问题,因为它不会尝试默认构造任何元素。空构造函数 returns 一个大小为 0 的向量,这意味着没有构造任何对象,从而避免了您未定义的默认构造函数。
原因是 std::vector<Foo> vec(10)
将实例化一个包含 10 个 "empty" Foo 对象的向量,即需要默认构造函数的 class Foo
的实例叫。但是,您的 class Foo
不提供默认构造函数。
第二条语句 std::vector<Foo> vec{}
实例化了一个空向量,因此没有实例化 Foo
-object(这需要默认构造函数)。
要解决您的问题,请在 Foo
:
struct Foo {
int bar;
Foo() : bar(0) {};
Foo(int _bar) : bar(_bar) { };
};