Consider this
void f(vector& p)
{
}
int main()
{
vector nonConstVec;
f(nonConstVec);
}
The followi
I've added a few lines to your code. That's sufficient to make it clear why this is disallowed:
void f(vector<const T*>& p)
{
static const T ct;
p.push_back(&ct); // adds a const T* to nonConstVec !
}
int main()
{
vector<T*> nonConstVec;
f(nonConstVec);
nonConstVec.back()->nonConstFunction();
}
Think of like this:
You have two class like this:
class V { T* t;};
class VC { T const* t;};
Do you expect these two classes to be convertible automatically?
This is basically what a template class is. Each variation is a completely new type.
Thus vector<T*> and vector<T const*> are completely different types.
My first question is do you really want to store pointers?
If yes, I would suggest looking at boost::ptr_container. This holds pointers and deletes them when the vector is destroyed. But more importantly it treats the contained pointers as a normal std:vector treats its contained objects. Thus by making the vector const you can only access its members as const
void function(boost::ptr_vector<T> const& x)
{
x.push_back(new T); // Fail x is const.
x[4].plop(); // Will only work if plop() is a const member method.
}
If you don't need to store pointers then store the objects (not the pointers) in the container.
void function(std::vector<T> const& x)
{
x.push_back(T()); // Fail x is const.
x[4].plop(); // Will only work if plop() is a const member method.
}
vector<T>
and vector<const T>
are unrelated types. The fact that T
can be converted to const T
doesn't mean a thing here.
You have to think about it from a type system's standpoint. Instantiated vector<int>
doesn't have anything in common with vector<const int>
.
As others have said, conversions aren't applied to the template parameters. Put another way,
vector<T>
...and:
vector<const T>
... are completely different types.
If you are trying to implement const-correctness in regard to f() not modifying the contents of the vector, this might be more along the lines of what you're looking for:
void f(vector<T>::const_iterator begin, vector<T>::const_iterator end)
{
for( ; begin != end; ++begin )
{
// do something with *begin
}
}
int main()
{
vector<T> nonConstVec;
f(nonConstVec.begin(), nonConstVec.end());
}