为什么std :: {container} :: emplace无法推断出其参数类型?

时间:2018-07-26 19:59:16

标签: c++ std

假设我有以下代码:

#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

1 个答案:

答案 0 :(得分:3)

这是由于以下事实:基于转发引用的完美转发因带有大括号的初始化程序列表而失败:对于编译器,这是“非推论上下文”。而是在将参数传递给容器的基础值类型构造函数时将其传递。

插入方法有所不同:它们接受const value_type&左值引用或右值引用(value_type&&)。因此,传递一个用于初始化类型的大括号初始化器列表可以很好地解决问题。