Const containers.

B

BigMan

Which is the preferred way to create a const container in general:

1. container_type< value_type > const; or
2. container_type< value_type const >?
 
I

Ivan Vecerina

BigMan said:
Which is the preferred way to create a const container in general:

1. container_type< value_type > const; or
2. container_type< value_type const >?
The latter should not compile.

So the only valid option is #2, e.g.:
std::vector<int> const cv( myArray, myArray+arraySize );
 
I

Ivan Vecerina

BigMan said:
This line compiles jsut fine:

std::vector< int const > v;

Just as many illegal C++ constructs may happen to compile on
one or more existing platforms.
The ISO C++ standard says in 23.1/3 about the type of
the elements of a container:
<<The type of objects stored in these components must meet the requirements
of CopyConstructible types (20.1.3), and the additional requirements of
Assignable types.>>
'int const' obviously isn't a type that fulfills the requirement of being
assignable.

Besides, even if 'vector<int const>' were legal, it would have
a number of drawbacks compared to 'vector<int> const'.
A key difference is that vector<int> can implicitly be converted
to a 'vector<int> const&', but not to a 'vector<int const>&'.

Cheers,
Ivan
 
B

BigMan

OK, but why does the standard allow creating std::vector< int const >?
This could very easily be forbidden, e.g.:

template< typename value_type >
vector< value_tyep const >;
 
B

BigMan

OK, but why does the standard allow creating std::vector< int const >?
This could very easily be forbidden, e.g.:

template< typename value_type >
vector< value_type const >;
 
I

Ivan Vecerina

BigMan said:
OK, but why does the standard allow creating std::vector< int const >?
This could very easily be forbidden, e.g.:

template< typename value_type >
vector< value_tyep const >;

The standard does not allow it - but it doesn't either
explicitly require the use of that technique to prevent it.

There is a number of similar safeguards that the standard
committee could have included, but never bothered to.
For example, "mix-in" base classes such as the 'struct iterator'
template would best have a protected destructor, to avoid
dangerous deletion through a base class pointer.

The reality is that these benevolent people have limited
resources, and a lot of higher-priority tasks to deal with.
 
H

Howard Hinnant

Ivan Vecerina said:
The standard does not allow it - but it doesn't either
explicitly require the use of that technique to prevent it.

There is a number of similar safeguards that the standard
committee could have included, but never bothered to.
For example, "mix-in" base classes such as the 'struct iterator'
template would best have a protected destructor, to avoid
dangerous deletion through a base class pointer.

The reality is that these benevolent people have limited
resources, and a lot of higher-priority tasks to deal with.

Agreed. But additionally the committee has little motivation to go
around requiring diagnostics on things that are likely to just fail at
compile time anyway. Especially if it is an area which could possibly
have extended functionality in a future standard. We do not want to
unnecessarily set up backwards compatibility problems for ourselves.

For example see:

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#276

which will make the OP's code legal in C++0X if the container type
changes to std::list. It is even likely to work today on all
implementations. :)

Indeed, I hope to see the requirements for a container's value_type
significantly relaxed for all of the containers in C++0X:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1771.html
23.1 - Container requirements

-3- The type of objects stored in these components must meet the requirements
of MoveConstructible and MoveAssignable types. Additionally for some member
functions (as noted below), the types must meet the requirements of
CopyConstructible and/or CopyAssignable types...

These changes would not make vector<const T> legal, but they would allow
a greater range of T to be put in a vector (a const T is not
MoveAssignable).

Another possibility for today is:

std::tr1::array<const int, 3> v = {1, 2, 3};

If your implementation does not provide std::tr1::array, perhaps you
could use boost::array instead:

http://www.boost.org/doc/html/array.html

All that being said, a safe alternative today is still const vector<T>.
:)

-Howard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,204
Messages
2,571,065
Members
47,672
Latest member
svaraho

Latest Threads

Top