I am trying to implace a class object into a std::map, and error occurs. Here is the code:
classes.hpp
#ifndef CLASSMETHODNOTCALLED_CLASSES_HPP
#define CLASSMETHODNOTCALLED_CLASSES_HPP
#include "iostream"
#include "memory"
// tow classes with one pointing to the other
class Ca
{
int m_va = 5;
public:
Ca();
int getVa();
};
class Cb
{
std::unique_ptr<Ca> m_x; // a smart ptr pointing to class Ca
int m_vb;
public:
explicit Cb(int n);
~Cb();
int getCa();
};
#endif //CLASSMETHODNOTCALLED_CLASSES_HPP
classes.cpp
#include "../include/classes.hpp"
#include "memory"
// Ca
Ca::Ca()
{
}
int Ca::getVa()
{
return m_va;
};
// Cb
Cb::Cb(int n)
{
m_x = std::make_unique<Ca>();
m_vb = n;
}
Cb::~Cb()
{
}
int Cb::getCa()
{
return m_x->getVa() + m_vb; // returns 5 + 1 = 6 if works properly
}
main.cpp
#include <iostream>
#include "include/classes.hpp"
#include "map"
int main()
{
Cb cb(1); // instanciate Cb
std::map<int, Cb> m;
m.emplace(1, cb); // the line where it complains: Call to implicitly deleted copy constructor
int i = m.at(1).getCa(); // should return 6 if working properly
// int i = cb.getCa(); // code without using std::map() works
std::cout << "va = " << i << std::endl;
}
I think it is caused by the smart pointer whose constructor is explicitly deleted. My question is, how to insert cb
into a std::map()
in this case? Thank you!
UPDATE:
Now I am trying to get a Cb object from the map, and here is what I did
int main()
{
Cb cb(1); // instanciate Cb
std::map<int, Cb> m;
m.emplace(1, std::move(cb));
Cb ccb = m.at(1); // error occurs here complaining Call to implicitly deleted copy constructor
int i = m.at(1).getCa();
// int i = cb.getCa();
std::cout << "va = " << i << std::endl;
}
Any idea?
emplace
takes parameters and forwards them to the contructor of the element of the map. If you pass it a Cb
it will copy it, if you pass it a rvalue ref it will move it and if you pass it a 1
it will use that to construct the Cb
.
Hence, you can
add a move constructor to Cb
(Cb(Cb&&)=default;
or rather remove your destructor then the compiler can generate both) and do
m.emplace(1,std::move(cb));
or construct the Cb
in place
m.emplace(1,1);
But you cannot ask emplace
to copy a Cb
because Cb
has no copy constructor.