Re: assignment of const class members
hi,
i tried a copy constructor, but the problem persist.
1 #include <vector>
2 #include <iostream>
3
4 struct A {
5 A(const unsigned int a) : u(a) {}
6 unsigned int u;
7 };
8
9 struct B {
10 B(const unsigned int a) : u(a) {}
11 B(const B& b) :u(b.u) {std::cerr<<" copy "<<std::endl;}
12 const unsigned int u;
13 };
14
15 int main () {
16
17 std::vector<A> p;
18 p.push_back(A(2)); // ok
19
20 B w(8); // ok
21 B x=w; // copy ok
22 B y(x); // copy ok
23 std::vector<B> z;
24 z.push_back(B(2)); // error
25 }
t.C: In member function 'B& B::operator=(const B&)':
t.C:9: instantiated from 'void std::vector<_Tp,
_Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename
_Alloc::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp =
B, _Alloc = std::allocator<B>]'
/usr/include/c++/4.0.0/bits/stl_vector.h:610: instantiated from
'void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = B,
_Alloc = std::allocator<B>]'
t.C:24: instantiated from here
t.C:9: error: non-static const member 'const unsigned int B::u', can't
use default assignment operator
/usr/include/c++/4.0.0/bits/vector.tcc: In member function 'void
std::vector<_Tp,
_Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename
_Alloc::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp =
B, _Alloc = std::allocator<B>]':
/usr/include/c++/4.0.0/bits/vector.tcc:260: warning: synthesized
method 'B& B::operator=(const B&)' first required here
On Dec 22, 9:47 am, Kira Yamato <kira...@earthlink.net> wrote:
On 2007-12-21 20:05:00 -0500, Salt_Peter <pj_h...@yahoo.com> said:
On Dec 21, 6:18 pm, Kira Yamato <kira...@earthlink.net> wrote:
On 2007-12-21 11:46:31 -0500, Salt_Peter <pj_h...@yahoo.com> said:
On Dec 21, 4:47 am, Kira Yamato <kira...@earthlink.net> wrote:
On 2007-12-21 03:38:33 -0500, hweek...@yahoo.com said:
hi,
it seems i can't assign the const variable u in class A, one way to
solve the problem may be to build a copy constructor. however, why
does C++ or vector class not like this code? my g++ is: gcc version
4.0.1 (Apple Inc. build 5465). thanks for the help.
summary of compile error:
---------------------------------------
cpp.C:4: error: non-static const member 'const unsigned int A::u',
can't use default assignment operator
/usr/include/c++/4.0.0/bits/vector.tcc:260: warning: synthesized
method 'A& A::operator=(const A&)' first required here
code:
-------
1
2 #include <vector>
3
4 struct A {
5 A(const unsigned int a) : u(a) { }
6 private: const unsigned int u;
7 };
8
9 int main () {
10
11 std::vector<A> y;
12 y.push_back(A(2));
13 }
You have a number of problems with this code.
First, when (12) is executed, std::vector tries to allocate an array of
struct A. Unfortunately, struct A has no default constructor. So, it
cannot construct each element in the array.
There is no array, he's trying to copy into the empty vector a single
element.
Preciously. So, before line (12) can assign the element A(2) into
std::vector, the program must invoke code to allocate an array first.
How else will std::vector<A> store A(12)?
There is no array in an empty vector. The vector is empty.
pushing back a parametized element requires no default construction
either.
As i already mentioned, to have a vector invoke a default ctor you
would have to tell it to do so.
std::vector< A > v; // does not invoke any of A's ctors
std::vector< A > v(10); // invokes A's default ctor + 10 copies
A vector is not an array.
Here is the proof:
#include <iostream>
#include <vector>
class A
{
int m_n;
public:
A() : m_n(0) { std::cout << "A()\n"; }
A(int n) : m_n(n) { std::cout << "A(int)\n"; }
A(const A& copy)
{
std::cout << "A(const A& copy)\n";
m_n = copy.m_n;
}
};
int main()
{
std::cout << "declaring an empty std::vector:\n";
std::vector< A > v;
std::cout << "v.size() = " << v.size() << std::endl;
std::cout << "pushing an element:\n";
v.push_back( A(99) );
std::cout << "v.size() = " << v.size() << std::endl;
std::cout << "default constructing 10 elements:\n";
std::vector< A > v2(10);
std::cout << "v2.size() = " << v2.size() << std::endl;
}
/*
declaring an empty std::vector:
v.size() = 0
pushing an element:
A(int)
A(const A& copy)
v.size() = 1
default constructing 10 elements:
A()
A(const A& copy)
A(const A& copy)
A(const A& copy)
A(const A& copy)
A(const A& copy)
A(const A& copy)
A(const A& copy)
A(const A& copy)
A(const A& copy)
A(const A& copy)
v2.size() = 10
*/
Indeed you're right! I had thought that the internal implementation of
std::vector<T> was with a pointer to an array of T's. Apparently, it
is a pointer to an array of T* instead.
It makes sense too. This way, you can push_back objects that do not
have default constructor.
Thanks for the correction.
--
-kira