【发布时间】:2018-08-13 22:43:23
【问题描述】:
假设我有这个代码:
#include <string>
#include <unordered_set>
struct command_node {
std::string key, value;
};
bool operator==(const command_node &x, const command_node &y) {
return x.key == y.key;
}
namespace std {
template<>
struct hash<command_node> {
typedef command_node argument_type;
typedef size_t result_type;
size_t operator()(const command_node &x) const {
return std::hash<std::string>()(x.key);
}
};
}
using command_set = std::unordered_set<command_node>;
int main(int argc, char **argv)
{
command_set commands;
commands.emplace(
command_node{"system", "running"}
);
return EXIT_SUCCESS;
}
它只是创建了一个 command_node 结构的 unordered_list。该代码仅用于说明。
问题:主要是这样(如上所示):
commands.emplace(
command_node{"system", "running"}
);
但事实并非如此:
commands.emplace(
{"system", "running"}
);
但是,如果我将 emplace 替换为 insert,则无论哪种方式都可以。换句话说,这是可行的:
commands.insert(
{"system", "running"}
);
为什么 emplace 不推断 command_node?
【问题讨论】:
-
因为
emplace函数都通过可变参数转发引用获取参数,这不会将大括号列表推断为任何内容。 -
你应该使用
commands.emplace("system", "running")。 -
@Jaa-c 仅当容器中的类型不是聚合时才有效(当然,具有采用这些参数类型的构造函数)
-
@Jaa-c 这适用于上面的代码(这只是一个简单的演示),但不适用于我的实际项目代码,其中第二个参数(“运行”)被替换为容器本身。第二个参数是 initializer_list 发挥作用的地方。
-
@BlairFonville 您可以在“真实代码”中使用
commands.emplace("system", Bar{x,y,z})。 Emplace 不是“递归的”。此外,这些大括号列表不是initializer_lists。