简体   繁体   中英

Constness of STL containers and their elements - when to use const?

I have been overthinking (some may say underthinking, let's see what happens) the const-ness of STL containers and their elements.

I have been looking for a discussion of this, but the results have been surprisingly sparse. So I'm not necessarily looking for a definite answer here, I'd be just as happy with a discussion that gets the gears in my head moving again.

Let's say I have a class that keeps std::strings in a std::vector. My class is a dictionary that reads words from a dictionary file. They will never be changed. So it seems prudent to declare it as

std::vector<const std::string> m_myStrings;

However, I've read scattered comments that you shouldn't use const elements in a std::vector, since the elements need to be assignable.

Question:

  • Are there cases when const elements are used in std::vector (excluding hacks etc)?

  • Are const elements used in other containers? If so, which ones, and when?

I'm primarily talking about value types as elements here, not pointers.

My class is a dictionary that reads words from a dictionary file. They will never be changed.

Encapsulation can help here.

Have your class keep a vector<string> , but make it private. Then add an accessor to your class that returns a const vector<string> & , and make the callers go through that.

The callers cannot change the vector, and operator [] on the vector will hand them const string & , which is exactly what you want.

,因为你陈述的原因。

In the context of std::vector , I don't think it makes sense to use a const qualifier with its template parameter because a std::vector is dynamic by nature and may be required to "move" in memory in order to "resize" itself.

In the C++03 standard, std::vector is guaranteed stored in contiguous memory. This almost requires that std::vector be implemented with some form of an array. But how can we create a dynamic size-changing array? We cannot simply just "append" memory to the end of it--that would either require an additional node (and a linked list) or actually physically putting our additional entries at the end of the array, which would be either out-of-bounds or require us to just reserve more memory in the first place.

Thus, I would assume that std::vector would need to allocate an additional array, copy or move its members over to the end array, and then delete the old one.

It is not guaranteed that a move or copy assignment for every template-able object for a std::vector would not change the underlying object being moved or copied--it is considered good form to do add the const qualifier, but it is not required. Therefore, we cannot allow a std::vector<const T> .

Related: How is C++ std::vector implemented?

consider using

std::vector<std::shared_ptr<const std::string>> 

instead?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM