a question about assignment


S

subramanian100in

Consider the following program:

#include <cstdlib>
#include <iostream>

using namespace std;

class Test
{
public:
// I have not made this ctor 'explicit' for learning purpose only
inline Test(int arg = 10);
Test &operator=(const Test &arg);

private:
int val;
};

inline Test::Test(int arg) : val(arg)
{
cout << "from test one arg ctor: " << val << endl;
}

Test &Test::eek:perator=(const Test &arg)
{
if (this != &arg)
{
val = arg.val;
cout << "Test::eek:perator=() called: " << val << endl;
}

return *this;
}

Test fn()
{
return Test();
}

int another()
{
int x = 100;
return x;
}

int main()
{
fn() = -1;
//another() = 100;

return EXIT_SUCCESS;
}

The above program compiles fine. However if I remove the comment
for the line
//another() = 100;
then I get compilation error
error: non-lvalue in assignment

The difference is that in 'fn() = -1', the function 'fn()' returns a
temporary object of user-defined type and so this temporary object
occupies a region of storage and therefore, it can be used as an
lvalue. However in the expression
another() = 100;
another() returns a built-in type value and hence cannot be used as an
lvalue.

Is my understanding correct ?

Thanks
V.Subramanian
 
Ad

Advertisements

C

Cupu

[snip]
The difference is that in 'fn() = -1', the function 'fn()' returns a
temporary object of user-defined type and so this temporary object
occupies a region of storage and therefore, it can be used as an
lvalue. However in the expression
another() = 100;
another() returns a built-in type value and hence cannot be used as an
lvalue.
[/snip]

Hi there,

in fact what you get from fn() is not an lvalue but the standard
allows implementations to invoke member functions (and only member
functions) on such temporary objects.

In the standard you can find this at 3.10.2:

An lvalue refers to an object or function. Some rvalue expressions—
those of class or cv-qualified class
type—also refer to objects.47)

*47) Expressions such as invocations of constructors and of functions
that return a class type refer to objects, and the implementation
can invoke a member function upon such objects, but the expressions
are not lvalues.


Stefan Constantin
 
Ad

Advertisements

N

Niels Dekker - no return address

V.Subramanian said:
The difference is that in 'fn() = -1', the function 'fn()' returns a
temporary object of user-defined type and so this temporary object
occupies a region of storage and therefore, it can be used as an
lvalue. However in the expression
another() = 100;
another() returns a built-in type value and hence cannot be used as an
lvalue.
in fact what you get from fn() is not an lvalue but the standard
allows implementations to invoke member functions (and only member
functions) on such temporary objects.

The next C++ Standard will allow you to specify that a specific member
function cannot be called on a temporary object, by adding a
ref-qualifier ('&') to the member function:

class Test
{
public:
Test(int arg = 10);
Test &operator=(const Test &arg) &; // <-- Ref-qualifier.
};

Test fn();

int main()
{
fn() = -1; // Compilation error in C++0x!
}

FYI, I'm busy writing a paper, proposing to the Standard committee to
add those ref-qualifiers to a lot of assignment operators in the
Standard Library. A preliminary version of this issue is at Howard
Hinnant's preview page of LWG issues: "Ref-qualifiers for assignment
operators"
http://home.roadrunner.com/~hinnant/issue_review/lwg-active.html#941


Kind regards,
 

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

Top