question on vector<T> and T::operator=()

S

subramanian100in

Suppose 'Test' is a class:

class Test
{
public:
....

private:
Test& operator=(const Test& rhs)
{
cout << "Test::eek:perator=() called" << endl;
}

};

Suppose I create
Test obj;

vector<Test> v;
v.push_back(obj);

Here I get compilation error because Test::eek:perator=() is private (I
kept it as private ONLY for learning purpose). However if I keep
Test::eek:perator=() as public, then it is not called for
'v.push_back(obj)'.

My doubt is, why does the compiler give error when Test::eek:perator=()
is private though it is not needed for push_back() operation ?

Kindly clarify.

Thanks
V.Subramanian
 
I

Ian Collins

Suppose 'Test' is a class:

class Test
{
public:
....

private:
Test& operator=(const Test& rhs)
{
cout << "Test::eek:perator=() called" << endl;
}

};

Suppose I create
Test obj;

vector<Test> v;
v.push_back(obj);

Here I get compilation error because Test::eek:perator=() is private (I
kept it as private ONLY for learning purpose). However if I keep
Test::eek:perator=() as public, then it is not called for
'v.push_back(obj)'.

My doubt is, why does the compiler give error when Test::eek:perator=()
is private though it is not needed for push_back() operation ?
The answer to your question is that the assignment operator may not be
called, but it is required to be public if defined.
 
G

gnuyuva

Suppose 'Test' is a class:

class Test
{
public:
...

private:
Test& operator=(const Test& rhs)
{
cout << "Test::eek:perator=() called" << endl;

}
};

Suppose I create
Test obj;

vector<Test> v;
v.push_back(obj);

Here I get compilation error because Test::eek:perator=() is private (I
kept it as private ONLY for learning purpose). However if I keep
Test::eek:perator=() as public, then it is not called for
'v.push_back(obj)'.

My doubt is, why does the compiler give error when Test::eek:perator=()
is private though it is not needed for push_back() operation ?

Kindly clarify.

Thanks
V.Subramanian

Think about copy constructor also ;-)
 
P

pelio

Ian Collins dixit:
The answer to your question is that the assignment operator may not be
called, but it is required to be public if defined.
$ cat tst1.cc ; echo ; make tst1 ; echo ; cat tst2.cc ; echo ; make tst2
; echo ; gcc --version
class A {
private:
A& operator=(const A& a) { return *this; }
};

int main() {}


g++ tst1.cc -o tst1

class A {
public:
A& operator=(const A& a) { return *this; }
};

int main() {}


g++ tst2.cc -o tst2

gcc (GCC) 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
K

Kai-Uwe Bux

Suppose 'Test' is a class:

class Test
{
public:
...

private:
Test& operator=(const Test& rhs)
{
cout << "Test::eek:perator=() called" << endl;
}

};

Suppose I create
Test obj;

vector<Test> v;
v.push_back(obj);

Here I get compilation error because Test::eek:perator=() is private (I
kept it as private ONLY for learning purpose). However if I keep
Test::eek:perator=() as public, then it is not called for
'v.push_back(obj)'.

My doubt is, why does the compiler give error when Test::eek:perator=()
is private though it is not needed for push_back() operation ?

Since the assignment operator is private, the class Test does not satisfy
the Assignable requirement. Therefore, the compiler is entitled to reject
your program. See [23.1/3-4].


Best

Kai-Uwe Bux
 
I

Ian Collins

pelio said:
Ian Collins dixit:
$ cat tst1.cc ; echo ; make tst1 ; echo ; cat tst2.cc ; echo ; make tst2
; echo ; gcc --version
class A {
private:
A& operator=(const A& a) { return *this; }
};

int main() {}

g++ tst1.cc -o tst1
I though it pretty obvious from the context I was referring to a class
that is to be stored in a standard container.
 
J

James Kanze

Suppose 'Test' is a class:
class Test
{
public:
...
private:
Test& operator=(const Test& rhs)
{
cout << "Test::eek:perator=() called" << endl;
}
};
Suppose I create
Test obj;
vector<Test> v;
v.push_back(obj);
Here I get compilation error because Test::eek:perator=() is private (I
kept it as private ONLY for learning purpose). However if I keep
Test::eek:perator=() as public, then it is not called for
'v.push_back(obj)'.
My doubt is, why does the compiler give error when
Test::eek:perator=() is private though it is not needed for
push_back() operation ?

Kai-Uwe has given you the formal reason---the one you need to
know: not providing an accessible assignment operator with
appropriate semantics is a contract violation, so anything the
implementation does is correct. Practically, if you're curious,
there are two reasons why it might fail to compile:

-- The library implementation uses concepts, using special code
to check and generate a compile time error if you violate
the requirements (up to a point---it can tell that you don't
have a publicly accessible assignment operator, but it
generally can't tell if you have one with inappropriate
semantics). G++ does this, at least with the right flags,
and I'm pretty sure that it's not alone.

In this case, of course, even the data definition, without
invoking any member function on it, will fail to compile.

-- Most library implementations of push_back simply call
insert. And insert almost certainly does use the assignment
operator. In a loop which will execute 0 times when the
insertion is at the end (as it always will be when insert is
called from push_back). So there's code there that invokes
assignment, even if it will never actually be executed given
the arguments you call the function with.
 

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

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,219
Latest member
KristieKoh

Latest Threads

Top