问题
I have declared the following in my code
vector <const A> mylist;
I get the following compile error -
new_allocator.h:75: error: `const _Tp* __gnu_cxx::new_allocator<_Tp>::address(const _Tp&) const \[with _Tp = const A]' and `_Tp* __gnu_cxx::new_allocator<_Tp>::address(_Tp&) const [with _Tp = const A]' cannot be overloaded
But if declare -
vector <A> mylist;
my code compiles.
Is const not allowed in this context?
I am copying my code here for everyone'e reference -
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
A () {cout << "default constructor\n";}
A (int i): m(i) {cout << "non-default constructor\n";}
private:
int m;
};
int main (void)
{
vector<const A> mylist;
mylist.push_back(1);
return 0;
}
回答1:
Items in a vector must be assignable (or, in more recent versions of the standard, movable). const
objects aren't assignable, so attempting to store them in a vector will fail (or at least can fail -- the code is invalid, but a compiler is free to accept it anyway, if it so chooses, though most programmers would generally prefer that invalid code be rejected).
I suppose for the truly pedantic, if you wanted to badly enough, you could define a type that was assignable despite being const
, something like this:
class ugly {
mutable int x;
public:
ugly const &operator=(ugly const &u) const {
x = u.x;
return *this;
}
};
I believe you should be able to store items of this type in a vector
even though they're const
. A quick test of creating a vector of these succeeds with VC++. This failed with some older compilers (e.g., failed with g++ 4.8.1), but works with reasonably recent ones (VC++ back to at least 2015, g++ back to at least 5.4 and clang++ back to at least 4.0--though I haven't tried to track down the first version of each that supported it).
For a current compiler, a type that supported moving const
objects would probably work just as well. But, just in case it wasn't obvious: this is allowing you to modify an object even though it's marked const
. That's clearly a direct violation of any reasonable user's expectations, so it's mostly a problem, not a solution.
回答2:
The use of the push_back
method is the problem. emplace_back
will compile.
Another alternative (depending on the whole situation you do not describe here) would be to use a vector<A const&>
if the inserted items have a life outside the vector.
Items in a vector do not need to be assignable, but when they are not, some member functions and algorithms can not be used.
Explanation :
push_back
is supposed to first default-construct an A in the vector, then assign (using copy-construct) the given reference. This breaks your const
qualification, hence does not compile.
emplace_back
uses "perfect forwarding" to invoke the actual constructor directly in place.
来源:https://stackoverflow.com/questions/17313062/vector-of-const-objects-giving-compile-error