You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用std::map::emplace添加不可移动类型的默认构造值

C++ std::map中仅传键默认构造值的方法

可编译代码示例

#include <map>

struct S {
    int val = 0;
    S() = default;
    S(S&&) = default;
};
int main() {
    std::map<int, S> values;
    values.emplace(42, S{});
}

这段代码能正常编译,因为S的移动构造函数可用,emplace可以将临时创建的S对象移动到std::pair的第二个成员中。

不可编译代码示例

#include <map>

struct S {
    int val = 0;
    S() = default;
    S(S&&) = delete;
};
class Wrapper {
   public:
    std::map<int, S> values;
    void AddEmptyValue(int key, int) { values.emplace(key, S{}); }
};

这段代码无法编译,原因很明确:我们创建了S的右值,但S的移动构造函数被删除,无法将这个右值移动到std::pair的第二个成员中。

解决方法:仅传键让值默认构造

要实现只传入键,就让对应的值在std::map内部默认构造,避免移动/拷贝操作,有几种可行的方式:

方式1:使用std::piecewise_construct(兼容C++11及以上)

通过std::piecewise_construct配合std::forward_as_tuple,分别传递键的构造参数和值的构造参数(值不需要参数,传递空tuple即可),这样std::pair会分别构造键和值,值会被默认构造:

#include <map>
#include <tuple>

struct S {
    int val = 0;
    S() = default;
    S(S&&) = delete;
};
class Wrapper {
   public:
    std::map<int, S> values;
    void AddEmptyValue(int key, int) {
        values.emplace(std::piecewise_construct,
                       std::forward_as_tuple(key),
                       std::forward_as_tuple());
    }
};

方式2:直接传递键参数(兼容C++11及以上)

std::map::emplace可以接受用来构造std::pair<const Key, T>的参数,当仅传递键时,std::pair会用该键构造第一个成员,同时默认构造第二个成员(只要T可默认构造):

#include <map>

struct S {
    int val = 0;
    S() = default;
    S(S&&) = delete;
};
class Wrapper {
   public:
    std::map<int, S> values;
    void AddEmptyValue(int key, int) {
        values.emplace(key);
    }
};

方式3:使用try_emplace(C++17及以上)

如果需要确保仅当键不存在时才插入新值,可以用try_emplace,同样仅传递键即可让值默认构造:

#include <map>

struct S {
    int val = 0;
    S() = default;
    S(S&&) = delete;
};
class Wrapper {
   public:
    std::map<int, S> values;
    void AddEmptyValue(int key, int) {
        values.try_emplace(key);
    }
};

内容的提问来源于stack exchange,提问作者Oersted

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 18:33:19