jvier
jvier

Reputation: 21

C++ constness on template type parameter

I'm working with standard containers like vector and pair using custom types as template arguments. Most times these template types are const-qualified, as in:

std::vector<const std::pair<const customType, const double>>

Hash () operators and comparison operators == and < have been defined.

Problem arises when I'm passing such values to standard library functions like partial_sort_copy, partial_sort and erase. For some reason, those functions eventually try to make assignments on the given types, ultimately failing at compilation due to the consts.

Is there any way to cast the consts out on template types for vector and pair? I.e., casting vector<const myType> to vector<myType>.

Thanks in advance.

EDIT: Now with conflicting minimum sample code!

// Non-working code:
std::vector<const std::pair<const int, const double>> list{ { 3, 3. }, { 2, 2. }, { 1, 1. }, { 0, 0. } };
std::partial_sort(list.begin(), list.begin() + 2, list.end(), [](const std::pair<const int, const double>& x, const std::pair<const int, const double>& y){ return x.first < y.first; });

// This works, actually:
std::vector<std::pair<int, double>> list{ { 3, 3. }, { 2, 2. }, { 1, 1. }, { 0, 0. } };
std::partial_sort(list.begin(), list.begin() + 2, list.end(), [](const std::pair<int, double>& x, const std::pair<int, double>& y){ return x.first < y.first; });

What is it about my code that the Standard Library won't like?

Upvotes: 2

Views: 124

Answers (1)

Jonathan Wakely
Jonathan Wakely

Reputation: 171263

Such containers of const types are undefined behaviour. A std::vector<const T> uses std::allocator<const T> as its allocator type, and the Allocator requirements say that the value type must be a non-const object type.

Even ignoring that ...

Is there any way to cast the consts out on template types for vector and pair? I.e., casting vector<const myType> to vector<myType>.

No.

In general some_template<T> and some_template<const T> are completely unrelated types, so you can't cast between them. There is no valid conversion between them, unlike const some_template<T> and some_template<T>.

So you should just stop using vectors of const objects. Instead use a const vector of non-const objects.

Upvotes: 4

Related Questions