Question

I am currently converting an application to 64 bit. I have some occurrences of the following pattern:

class SomeOtherClass;

class SomeClass
{
    std::vector<SomeOtherClass*> mListOfThings;

    void SomeMemberFunction (void)
    {
        // Needs to know the size of the member list variable
        unsigned int listSize = mListOfThings.size();

        // use listSize in further computations
        //...
    }
}

Obviously in a practical case I will not have more then MAX_INT items in my list. But I wondered if there is consensus about the 'best' way to represent this type.

Each collection defines its own return type for size(), so my first approximation would be:

std::vector<SomeOtherClass*>::size_type listSize = mListOfThings.size()

I would assume this to be correct, but (personally) I dont find this 'easy reading', so -1 for clarity.

For a c++011 aware compiler I could write

auto listSize = mListOfThings.size()

which is clearly more readable.

So my question, is the latter indeed the best way to handle storing container sizes in a variable and using them in computations, regardless of underlying architecture (win32, win64, linux, macosx) ?

Was it helpful?

Solution

What exactly you want to use is a matter of how "purist" you want your code to be.

If you're on C++11, you can just use auto and be done with.

Otherwise, in extremely generic code (which is designed to work with arbitrary allocators), you can use the container's nested typedef size_type. That is taken verbatim from the container's allocator.

In normal use of standard library containers, you can use std::size_t. That is the size_type used by the default allocators, and is the type guaranteed to be able to store any object size.

I wouldn't recommend using [unsigned] int, as that will likely be smaller than necessary on 64-bit platforms (it's usually left at 32 bits, although this of course depends on compiler and settings). I've actually seen production code fail due to unsigned int not being enough to index a container.

OTHER TIPS

It depends on why you need the size, and what is going to be in the vector. Internally, vector uses std::size_t. But that's an unsigned type, inappropriate for numerical values. If you just want to display the value, or something, fine, but if you're using it in any way as a numerical value, the unsignedness will end up biting you.

Realistically, there are a lot of times the semantics of the code ensure that the number of values cannot be more than INT_MAX. For example, when evaluating financial instruments, the maximum number of elements is less than 20000, so there's no need to worry about overflowing an int. In other cases, you'll validate your input first, to ensure that there will never be overflow. If you can't do this, the best solution is probably ptrdiff_t (which is the type you get from subtracting to iterators). Or if you're using non-standard allocators, MyVectorType::difference_type.

Not sure if you've already considered this, but what is wrong with size_t? It is what you compiler uses for sizes of builtin containers (i.e. arrays).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top