2017-09-01 5 views
2

J'essaie d'insérer une instance d'une classe modèle qui n'a pas de constructeur de copie dans une carte. Le code ci-dessous ne fonctionne pas, car à la fonction emplace le compilateur veut appeler le constructeur de copie. Je ne comprends pas pourquoi, parce que je compris de la C++ reference que emplace ne se déplace pas ou copier:Insérer une classe modèle dans std :: map avec construction à l'insertion

Une utilisation judicieuse de emplace permet le nouvel élément à construire tout en évitant copie inutile ou de déplacement.

Ceci est mon code:

#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

Pourquoi? Si c'était mobile mais non-copie cela aurait fonctionné bien. – CoryKramer

Répondre

2

Vous pouvez utiliser std::piecewise_construct et std::forward_as_tuple pour créer vos objets en place.

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

live wandbox example


std::map::emplace parfaitement en avant un tas d'arguments à la std::pair sous-jacent utilisé pour le stockage clé/valeur. std::pair::pair a une surcharge qui prend un std::piecewise_construct_t comme premier argument, puis deux std::tuple instances: le premier sera utilisé pour construire .first en place, le second sera utilisé pour construire .second en place.

De cppreference, en ce qui concerne le constructeur piecewise de std::pair:

Transmet les éléments de first_args au constructeur de first et transmet les éléments de second_args au constructeur de second. C'est le seul constructeur non-par défaut qui peut être utilisé pour créer une paire de types non-déplaçables non-mobiles. Pourquoi ne pas rendre la classe non mobile?

+0

Dans ce cas particulier, «tie» est plus court. –