我需要在以下代码中向矢量“项目”中手动添加项目,但出现错误“ emplace_back':函数未使用5个参数”-如何使它工作?
enum class ITM {
...
};
enum class RES {
res1,
res2
};
typedef std::vector<std::pair<RES,int>> ingredient_list;
struct _item {
ITM name;
double buy, sell, craft;
ingredient_list ingr;
};
std::vector<_item> items;
items.emplace_back(ITM::lm54, 0, 0, 0, { {RES::res1, 50}, {RES::res2, 70} });
答案 0 :(得分:1)
类型_item
没有带有五个参数的构造函数,但是可以使用move构造函数。
items.emplace_back(_item{ ..., ..., ..., ..., ... });
emplace_back()
试图找到_item
的构造函数,该构造函数接受相同的参数,以便在调用此构造函数的过程中转发。
move构造函数隐式存在(除非明确禁用或被某些数据成员禁用),因此提供临时_item
作为emplace_back()
的参数可以很好地将其转发到将使用的move构造函数用于在向量内部进行就地构建。
答案 1 :(得分:1)
您可以这样做:
std::vector<_item> items{
{ ITM::Foo, 1., 2., 3., { { RES::res1, 1 } } },
{ ITM::Bar, 4., 5., 6., { { RES::res1, 2 }, { RES::res2, 3 } } }
};
答案 2 :(得分:1)
您的代码为什么不起作用?因为两件事。
emplace_back
会扣除参数,并且您已经传递了初始化列表({}
前面没有任何类型)。初始化程序列表在模板推导上不能很好地工作(实际上,它们根本不起作用,例如:
template <typename F> void foo(F &&f)
{
std::vector<int> q = f;
}
int main()
{
foo({ 1 });
}
产生可怕的东西
prog.cpp: In function ‘int main()’:
prog.cpp:12:11: error: no matching function for call to ‘foo(<brace-enclosed initializer list>)’
foo({ 1 });
^
prog.cpp:5:28: note: candidate: template<class F> void foo(F&&)
template <typename F> void foo(F &&f)
^~~
prog.cpp:5:28: note: template argument deduction/substitution failed:
prog.cpp:12:11: note: couldn't deduce template parameter ‘F’
foo({ 1 });
^
要对此进行修改,您需要添加类型:
items.emplace_back(ITM::lm54, 0, 0, 0, ingredient_list{ {RES::res1, 50}, {RES::res2, 70} });
第二,这是您的items_
类型是POD(纯旧数据-没有构造函数,没有其他东西)。编译器允许您使用构造函数语法(_item(values)
来初始化POD类型,但这不能与vector
(和其他容器)一起使用,因为它们在这样的内部使用:
::new((void *)__p) _Up(std::forward<_Args>(__args)...);
忽略POD事物。因此,您要么需要在类型名前面加上参数(从而创建对象并强制编译器使用move构造函数),要么在类中定义构造函数(从而避免出现整个POD问题)。
答案 3 :(得分:1)
您的代码无法正常工作,因为您需要_item
的构造函数,该构造函数需要使用所有5个参数,并且看来您没有一个。
幸运的是,从C ++ 11开始,您可以使用list_initialization:
items.push_back({ITM::lm54, 0, 0, 0, { {RES::res1, 50}, {RES::res2, 70} }});
您只需将初始化项所需的信息放在花括号之间即可。这应该创建一个_item
对象,然后将其推入容器。