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);
}
CodePudding user response:
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*>>
.