2017-09-01 83 views
2

我想将没有复制构造函数的模板类的实例插入到映射中。下面的代码不起作用,因为在emplace函数编译器想调用复制构造函数。我不明白为什么,因为我从布设不移动或复制C++ reference理解:在std :: map中插入模板类,并在构建时插入

谨慎使用布设的允许建造的新元素,同时 避免不必要的复制或移动操作。

这是我的代码:

#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; 
} 
+0

为什么要让班级不可移动?如果它是可移动的,但不可复制,这将工作得很好。 – CoryKramer

回答

2

您可以使用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 example


std::map::emplace完全向前一堆参数用于密钥/值存储底层std::pairstd::pair::pair有一个超载,它将std::piecewise_construct_t作为第一个参数,然后是两个std::tuple实例:第一个将用于构建.first,第二个将用于构建.second

从cppreference,关于std::pair的分段构造:

转发的first_argsfirst构造元素和转发的second_argssecond构造的元素。这是唯一可用于创建一对不可复制的不可移动类型的非默认构造函数。

+0

在这种特殊情况下,'领带'较短。 –