I use third party containers that use int
to store the size. I also use stl containers which use size_t
to store size.
I very often in my code have to use both in the same loop, like for example:
// vec is std::vector
// list is the third party container
assert(vec.size() == list.size()); // warning
for(size_t i = 0; i < vec.size(); i++)
{
vec[i] = list[i]; // warning
}
So to fix I have to either I do function style casting, which I was told is C style casting in disguise.
// vec is std::vector
// list is the third party container
assert(int(vec.size()) == list.size());
for(size_t i = 0; i < vec.size(); i++)
{
vec[i] = list[int(i)];
}
Or I can do the even uglier solution that everyone recommends. The static casting.
// vec is std::vector
// list is the third party container
assert(static_cast<int>(vec.size()) == list.size());
for(size_t i = 0; i < vec.size(); i++)
{
vec[i] = list[static_cast<int>(i)];
}
I really don't want to static_cast
.
int
to size_t
or size_t
to int
?Thank you.
Binary operators (operator==
here) convert signed integers to unsigned if one of the arguments is unsigned. A signed negative integer turns into a big positive one.
Container element count must not be negative to avoid breaking the principle of least surprise. So, the implicit conversion must be safe. But be sure to check the implementation/documentation of int size() const
.
You may like to preserve the semantics of the implicit conversion and use as_unsigned
function to avoid the cast and better convey the intent:
#include <type_traits>
template<class T>
inline typename std::make_unsigned<T>::type as_unsigned(T a) {
return static_cast<typename std::make_unsigned<T>::type>(a);
}
and then:
assert(vec.size() == as_unsigned(list.size()));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With