I don’t understand when we can use const variables/objects in collections (particularly with emplace). The below code works with const objects directly but not when using pointers to const objects.
#include <list>
class MyData { };
int main() {
std::list<std::pair<int, MyData>> collection1{};
std::list<std::pair<int, MyData*>> collection2{};
const MyData someData{};
const MyData* someDataPtr = &someData;
collection1.emplace_back(1, someData);
//collection2.emplace_back(1, someDataPtr); //Messy template error!
}
I assume there’s not much advantage to using emplace_back over push_back for pointers, but I’m using std::pair to illustrate that the other part of the pair could be something big/costly.
Specifically, my question is why does emplace_back work with a const object but not a pointer to a const object? Is there a reasonable way to achieve the latter?
For anyone wondering about the use-case, I have a member function which is passed the constituents of the pair, does some processing (but should not change any data) and then emplaces the pair to the collection. Something like:
void add_to_schedule(const int id, const MyData* myData) {
//some processing
this->collection.emplace_back(id, myData);
}
>Solution :
const MyData* can’t be converted to MyData* implicitly. That means std::pair<int, MyData*> can’t be constructed from {1, someDataPtr} while someDataPtr is a const MyData*.
Under the same logic,
MyData* p = someDataPtr; // fails
MyData m = someData; // fine
As the workaround, you can change someDataPtr to MyData*, or change the std::list to std::list<std::pair<int, const MyData*>>.