🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Size doesn't really matters...right?

Started by
54 comments, last by JoeJ 6 years, 9 months ago

but while


int f(int& n)
{
    n += 99;
    return n; // copies the value referred to by n
}

won't compile in my example from the previous page, the code below will:


string f(string& n)
{
	return n += "99";
}

and the signature is the same,both take a reference and return by value! So what is actually happening here?

My current guess is that the first one at the return stage is doing


int ??? = n;

and the other is doing


string ??? = n;

so the only difference must be the overload on operator=

So in the int case the overload must be


int operator=(int,int)

while in the string case is


string& operator=(string,string)

So is this the case? operator= is behaving differently for the primitive types?

Advertisement
26 minutes ago, MarcusAseth said:

won't compile in my example from the previous page, the code below will:


int f(int& n) {
    n += 99;
    return n;
}

int main() {
  int a = 5;
  const int b = f(a);
}

This compiles fine. Your assignment f(a) = ... won't.

26 minutes ago, MarcusAseth said:

string& operator=(string,string)

The assignment operator signature looks like:


string &operator=(const string &)

for ints there is similarly a:


int &operator=(const int &)

and you can perfectly assign:


int a = 5;

a = 6;

 

🧙

4 minutes ago, matt77hias said:

This compiles fine. Your assignment f(a) = ... won't.

yes, and the f(a)= with string will compile, that's why I'm trying to understand why's the difference.

this


 const int b = f(a);

this above totally deviate the discussion and is besides my point, I know that will compile :P

Just now, MarcusAseth said:

that's why I'm trying to understand why's the difference.


int a = 5;

a = 6;

is not the same as:


5 = 6;

For the latter does not exist an assignment operator.

🧙

7 minutes ago, matt77hias said:


int a = 5;

a = 6;

is not the same as:



5 = 6;

For the latter does not exist an assignment operator.

Matt I don't know if you're misunderstanding my question on purpose or what... :D

I'll recap my question in case anyone knows:

Why this code below compiles:


string f(string& n)
{
	return n += "99";
}

int main() {
	string a = "";
	string b = "!!!";
	
	f(a) = b;//COMPILE
}

While the one below doesnt?


int f(int& n)
{
	return n += 99;
}

int main()
{
	int a = 1;
	int b = 7;

	f(a) = b;//WON'T COMPILE
}

Both functions return by value and take an argument by reference.

Is it a difference in how operator=() is implemented for primitive types? Or what?

You cannot assign built-in types: float, double, (unsigned) int, (unsigned) long, (unsigned) long long, (unsigned) short, (unsigned) char, etc.

So yes, this behavior is different from std::string::operator=(const std::string &).

But like I said:


int a = 5;

a = 6; // clearly an assignment to an lvalue int -> see below: assigning to int

5 = 6; // you cannot assign to an rvalue int -> see below: assigning to const int

wheareas:


std::string a("5");

a = "6"; // clearly an assignment to an lvalue std::string

std::string f() { return std::string a("5"); }

f() = "6"; // you can assign to an rvalue std::string

And I am not really sure, but I see no way to avoid assigning to an rvalue built-in type via the C++ language features itself. It must be dealt with and enforced by the compiler.

Edit: it has nothing to do with lvalue/rvalue assignment, but with implicit constness (see below).

🧙

Ok, after some reasoning I found the solution :P (you confused me by adding lvalue/rvalue to the discussion ;) )

 

int a = 5;

a = 6; // clearly an assignment to a (non-constint

5 = 6; // you cannot assign to a const int

If you specify built-in constant values, they are treaten as const and are thus not assignable.

 

int f() { return 5; } == const int f() { return 5; }

int f(int &n) { return n; } == const int f(int &n) { return n; }

If you return by value of a built-in type, you return by const value of a built-in type. The former is implicitly equal to the latter. You normally do not write the const in this case, though it is implicitly there!

 

So you basically do not allow an assignment operator since the latter mutates the int/std::string.

 

@MarcusAseth Makes sense now? :)

🧙

I need more convincing, so I went and opened the C++ standard for the first time (scary), see what I could find.

I've found this:

Quote

An lvalue for an object is necessary in order to modify the object except that an rvalue of class type can
also be used to modify its referent under certain circumstances. [ Example: a member function called for an
object (9.3) can modify the object. — end example ]

So basically:


string f(string& n)
{
	return n += "99";
}

int main() {
	string a = "";
	string b = "!!!";
	
	f(a) = b;//COMPILE
}

is working because


f(a) = b;

in reality is doing


f(a).operator=(b);

 

So the difference why it doesn't work with built-in type must be this, built-in type doesn't have a member function operator=()

 

Now I think I can rest in peace :D

1 minute ago, MarcusAseth said:

So the difference why it doesn't work with build in type must be this, build in type doesn't have a member function operator=()

No!!!

3th time I repeat this:

 

int a = 5;

a = 6; // clearly an assignment to a (non-constint

 

I clearly see the implicit a.operator=(6); which is an assignment.

🧙

1 minute ago, matt77hias said:

No!!!

3th time I repeat this:

 

int a = 5;

a = 6; // clearly an assignment to a (non-constint

 

I clearly see the implicit a.operator=(6); which is an assignment.

int don't have member functions, it can't be the case :\

This topic is closed to new replies.

Advertisement