Q:

Const container returning non-const references

It makes sense in my head, but I'm not sure if this is proper const-correctness.
I have a container like this:
template<typename T>
class IDMap
{
public:
    typedef uint64_t ItemID;

    T& GetItem(const ItemID id) const
    {
        const uint32_t index = _IDSTORAGE_INDEX_MASK(id);
        const uint32_t version = _IDSTORAGE_VERSION_MASK(id);

        assert(mItems[index].mVersion == version);

        return mItems[index].mItem;
    }

    // ....
};

I can delegate const references to this container to other classes knowing full well they cannot modify the container, but they can access and modify it's objects.
Is this a valid case? Valid as in  "This solves a specific problem for me, but I'm not sure if its good practice"

A:

It depends.
Const correctness gets pretty subtle when it comes to references held by objects. If you have a dynamic array class, with a pointer to the current array of values, technically you can modify those pointed-to values from within a const function... but you probably shouldn't, because that means the const function is changing "the dynamic array object", even if the object itself isn't changing. The array owns those values, and their constness should be protected by its own.
But if your object is not the owner of the pointed-to objects, then giving out non-const references to them is generally the right thing to do. In that case, the constness of your object extends only to the identity of the objects in the mapping, not what values are inside of them.

A:

It's not usually considered const-correct. However, the simple fact is that the language does not really permit a correct use of const in this scenario. For example, you can't say std::vector<const T>. Even if you fixed your IDMap to support such usage, it still wouldn't support things like covariance on constness.
Your choices are one bad use of const or another bad use of const, so take your pick.
What's more concerning is this _IDSTORAGE_VERSION_MASK. Using _U-style names in user code is undefined behaviour.

