C++ std::vector::emplace_back 不能用字符串值 class 编译
C++ std::vector::emplace_back doesn't compile with string-value class
/* Item.h */
struct Item {
std::string name;
Item(std::string _name) : name( std::move(_name) ) { }
};
/* main.cpp */
/* ... */
const int amount_of_items = val.size();
std::vector<Item> items(amount_of_items);
for( Json::Value::const_iterator itr = val.begin() ; itr != val.end() ; ++itr ) {
items.emplace_back( "item_name" );
}
结果:
/usr/include/c++/8/bits/stl_construct.h:75:7: error: no matching function for call to ‘Item::Item()’
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from main.cpp:8: Item.h:8:2: note: candidate: ‘Item::Item(std::__cxx11::string)’ Item(std::string _name) : name( std::move(_name) ) { } ^~~~ Item.h:8:2: note: candidate expects 1 argument, 0 provided
我不知道为什么这行不通 - 有什么想法吗?
您的结构中没有默认构造函数,因为您添加了一个非默认构造函数。您可以添加回您的默认构造函数。
但错误行实际上是您的初始化(项目数量),这是试图使用默认 c'tor 默认构造 item
s。
所以我建议你添加一个默认的 c'tor:
Item() = default;
或者用字符串初始化:
std::vector<Item> items(num_items, std::string(""));
此外,您的 'move' 构造函数应使用 r-value ref &&
(并且可能也是显式的,因为它只有一个参数):
Item() = default;
// here
// V
explicit Item(std::string &&_name) : name( std::move(_name) ) { }
调用std::vector
构造函数时:
std::vector<Item> items(amount_of_items);
包含类型的默认构造函数:Item
被调用。您应该定义一个默认构造函数:
Item() = default
或使用其他 std::vector
没有此要求的构造函数之一:
std::vector<Item> items(amount_of_items, {""});
这条语句:
std::vector<Item> items(amount_of_items);
需要 Item
的默认构造函数,因为您已要求编译器使用 amount_of_items
默认构造的 Item
s.
填充数组
相反,你需要简单地写:
std::vector<Item> items;
因为 emplace_back
会根据需要增加数组。
请注意,如果您想预先为 Item
预留 space,您可以 致电 items.reserve
。
问题是您需要 Item
这个代码序列的默认构造函数。默认构造函数被禁用,因为您有 Item
.
的自定义构造函数
您可以通过添加 Item()=default;
来启用它。
除此之外,您还有一个逻辑错误:std::vector<Item> items(amount_of_items);
启动了 items
到 amount_of_items
的默认构造元素。根据下一个序列,这不是您想要的,因为到最后您将拥有双倍数量的元素。
你应该写
std::vector<Item> items;
items.reserve(amount_of_items);
/* Item.h */
struct Item {
std::string name;
Item(std::string _name) : name( std::move(_name) ) { }
};
/* main.cpp */
/* ... */
const int amount_of_items = val.size();
std::vector<Item> items(amount_of_items);
for( Json::Value::const_iterator itr = val.begin() ; itr != val.end() ; ++itr ) {
items.emplace_back( "item_name" );
}
结果:
/usr/include/c++/8/bits/stl_construct.h:75:7: error: no matching function for call to ‘Item::Item()’
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from main.cpp:8: Item.h:8:2: note: candidate: ‘Item::Item(std::__cxx11::string)’ Item(std::string _name) : name( std::move(_name) ) { } ^~~~ Item.h:8:2: note: candidate expects 1 argument, 0 provided
我不知道为什么这行不通 - 有什么想法吗?
您的结构中没有默认构造函数,因为您添加了一个非默认构造函数。您可以添加回您的默认构造函数。
但错误行实际上是您的初始化(项目数量),这是试图使用默认 c'tor 默认构造 item
s。
所以我建议你添加一个默认的 c'tor:
Item() = default;
或者用字符串初始化:
std::vector<Item> items(num_items, std::string(""));
此外,您的 'move' 构造函数应使用 r-value ref &&
(并且可能也是显式的,因为它只有一个参数):
Item() = default;
// here
// V
explicit Item(std::string &&_name) : name( std::move(_name) ) { }
调用std::vector
构造函数时:
std::vector<Item> items(amount_of_items);
包含类型的默认构造函数:Item
被调用。您应该定义一个默认构造函数:
Item() = default
或使用其他 std::vector
没有此要求的构造函数之一:
std::vector<Item> items(amount_of_items, {""});
这条语句:
std::vector<Item> items(amount_of_items);
需要 Item
的默认构造函数,因为您已要求编译器使用 amount_of_items
默认构造的 Item
s.
相反,你需要简单地写:
std::vector<Item> items;
因为 emplace_back
会根据需要增加数组。
请注意,如果您想预先为 Item
预留 space,您可以 致电 items.reserve
。
问题是您需要 Item
这个代码序列的默认构造函数。默认构造函数被禁用,因为您有 Item
.
您可以通过添加 Item()=default;
来启用它。
除此之外,您还有一个逻辑错误:std::vector<Item> items(amount_of_items);
启动了 items
到 amount_of_items
的默认构造元素。根据下一个序列,这不是您想要的,因为到最后您将拥有双倍数量的元素。
你应该写
std::vector<Item> items;
items.reserve(amount_of_items);