Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Guarantee that std::container::size_type is a std::size_t

Tags:

Following this question, I decided to use std::size_t as size_type for every containers, for obvious readability reasons. I know it's theorically possible that std::container<T>::size_type is not std::size_t, but I assume it's not the case on my current and future configurations.

However, in order to avoid wicked bugs, I check the types are the same when I use them. For example:

BOOST_STATIC_ASSERT(boost::is_same< std::vector<double>::size_type , std::size_t >::value);
std::vector<double> x;
/* fill x */
for(std::size_t i = 0; i < x.size(); ++i) { /* do something */ }

Another place in the code, I use a std::vector<long int>, then I also check:

BOOST_STATIC_ASSERT(boost::is_same< std::vector<long int>::size_type , std::size_t >::value);

And then, oh no! I use std::vector<std::list<std::string>*> and std::vector<std::list<double*>*>, then I check:

BOOST_STATIC_ASSERT(boost::is_same< std::vector<std::list<std::string>*>::size_type , std::size_t >::value);
BOOST_STATIC_ASSERT(boost::is_same< std::vector<std::list<double*>*>::size_type , std::size_t >::value);

Ok, I think you understand the problem. Ugly lines, difficult to maintain the code. It's a bad idea.

Then, my question is: If I check std::vector<any_common_type>::size_type is a std::size_t, is there any chance that std::vector<another_type>::size_type is NOT std::size_t ? Is it enough to only check some common types in a separated file to be sure std::container::size_type is always std::size_t on my compiler ?

Note: I don't use C++11 for compatibility reasons.

like image 750
Caduchon Avatar asked Sep 07 '17 08:09

Caduchon


1 Answers

The approach you follow in your question seems to be the way to go, if you really need to do this.

However, I think you worry too much, since size_t can handle size_type.

If you ever find yourself in the unlikely situation where a platform implements size_t in a way that makes not big enough to contain all the values of size_type, then I am pretty sure that you will receive a compiler warning on any comparison you will attempt to perform.

'size_t' vs 'container::size_type' mentions:

The standard containers define size_type as a typedef to Allocator::size_type (Allocator is a template parameter), which for std::allocator is typically defined to be size_t (or a compatible type). So for the standard case, they are the same.


So, if I were you I would be confident about my compiler to lie in the typical case. However, if I did use non-standard containers, then I would bother to follow your - as you said ugly - approach, put it in a file and let it do its job in a hidden dark corner.

like image 122
gsamaras Avatar answered Sep 30 '22 15:09

gsamaras