2017-09-01 136 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

在這種特殊情況下,'領帶'較短。 –