在插入时插入std :: MAP中的模板类

Insert templated class in std::map with construction at insertion

本文关键字:插入 MAP std      更新时间:2023-10-16

我正在尝试插入一个模板类的实例,该类别没有复制构造函数。下面的代码不起作用,因为在emplace功能上,编译器要调用复制构造函数。我不明白为什么,因为我从c 参考中理解了emplace不会移动或复制:

仔细使用EMPLECE可以构建新元素 避免不必要的副本或移动操作。

这是我的代码:

#include <map>
#include <string>
template<typename T> class Class_a
{
    public:
        Class_a(T t1, T t2) : t1_(t1), t2_(t2) {}
        ~Class_a() {}
        Class_a(const Class_a&) = delete;
        Class_a& operator=(const Class_a&) = delete;
        Class_a(Class_a&&) = delete;
    private:
        const T t1_;
        const T t2_;
};
template<typename T>
using Class_a_map = std::map<std::string, Class_a<T>>;
int main()
{
    Class_a_map<double> class_a_map;
    std::string name = "test";
    double number1 = 42;
    double number2 = 43;
    class_a_map.emplace(name, Class_a<double>(number1, number2));
    return 0;
}

您可以使用std::piecewise_constructstd::forward_as_tuple来创建对象。

class_a_map.emplace(
    std::piecewise_construct, 
    std::forward_as_tuple(name),
    std::forward_as_tuple(number1, number2)
);

live wandbox示例


std::map::emplace完美地将一堆参数转发到用于键/值存储的基础std::pairstd::pair::pair的过载将std::piecewise_construct_t作为其第一个参数,然后将两个std::tuple实例用于:第一个实例将用于构造.first,第二个将用于构造.second

来自cppreference,涉及std::pair的分段构造函数:

first_args的元素转发到first的构造函数,并将second_args的元素转发到second的构造函数。这是唯一可用于创建一对不可移动类型的非默认构造函数。