473,695 Members | 2,421 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

const reference vs. value

Dear members of comp.lang.c++,
I am a little bit confused about the differences between constant
references and values. I understand that it is faster to use a constant
reference ("const T&") than a value ("T") since the former does not
require copying whereas the latter does, is that correct? Also, I un
derstand that "const T&" allows for polymorphism whereas "T" will
generate code cuttting.
On the former points, I am fairly confident... But I'm somewhat
confused on how the two influence conversions. For example, suppose I
define the following type:

class Real{
public:
Real(int)
Real(float);
Real(double);
Real(long double);
...
Real operator+(Real) ;
};

Can I now write the following?
Real x = 5.0;
Real y = x + 3;
//is above legal now if I don't define Real::operator+ (int)?

Now, suppose I change the declaration+def inition of
Real::operator+ (Real) to Real::operator+ (const Real&), is the above
still legal? Or do I need to modify the above to the following?

Real x = 5.0;
Real tmp = 3;
Real y = x + tmp;

*************** *************** ********

In short, can one convert an unnamed constant to a constant reference or
only to a value?
Aug 17 '06 #1
8 4090
Michael Safyan posted:
Dear members of comp.lang.c++,
I am a little bit confused about the differences between constant
references and values. I understand that it is faster to use a constant
reference ("const T&") than a value ("T") since the former does not
require copying whereas the latter does, is that correct?

Generalised answer: For large user-defined types, yes. For built-in types,
no.

In C++, references are "magical". The Standard says everything about how
they behave, but absolutely nothing about what they actually are.

In C, everything was passed by value, and everything was returned by value.
If you wanted to alter an object in the calling function, then you passed
its address. There was one other time, however, in C, where you passed the
object's address: when the object type was large and it would have been
more efficient to pass its address rather than passing the object by value.

As mysterious as references may be, they're still apart of our world, and
must obey the laws of our physics and so forth. If you have a scenario such
as:

struct PictureInfo {

unsigned width;
unsigned height;
unsigned colour_depth;

/* More members */
};

void Func(PictureInf o const &info)
{
/* Do stuff with the object */
}

Then the compiler will treat it as if you wrote:

void Func(PictureInf o const *const p)

For the most part, references are exactly like const pointers -- const
pointers which you don't have to dereference.

There's something special about "references to const" though. If you bind a
"reference to const" to an R-value, then an object is created which lives
until the reference goes out of scope. Writing the following:

{
int &r = 5;
}

is effectively like writing:

{
int const five = 5;
int &r = five;
}

Also, I un derstand that "const T&" allows for polymorphism whereas "T"
will generate code cuttting.

Indeed. In general though, you should always be passing user-defined
objects by reference to const, rather than by value.

On the former points, I am fairly confident... But I'm somewhat
confused on how the two influence conversions. For example, suppose I
define the following type:

class Real{
public:
Real(int)
Real(float);
Real(double);
Real(long double);
...
Real operator+(Real) ;
};

Can I now write the following?
Real x = 5.0;
Real y = x + 3;
//is above legal now if I don't define Real::operator+ (int)?

Question to Physics teacher:
"I have an apple in my hand; if I let go of it, will gravity pull it to
the ground?"

Answer from Physics teacher:
"Why are you asking *me* when you can try compile it with your own
compiler?"

Now, suppose I change the declaration+def inition of
Real::operator+ (Real) to Real::operator+ (const Real&), is the above
still legal? Or do I need to modify the above to the following?

Would it be legal if you passed its address? References are just a fancy
way of passing around addresses.

--

Frederick Gotham
Aug 17 '06 #2
Frederick Gotham wrote:
Michael Safyan posted:
>Dear members of comp.lang.c++,
I am a little bit confused about the differences between constant
references and values. I understand that it is faster to use a constant
reference ("const T&") than a value ("T") since the former does not
require copying whereas the latter does, is that correct?


Generalised answer: For large user-defined types, yes. For built-in types,
no.

In C++, references are "magical". The Standard says everything about how
they behave, but absolutely nothing about what they actually are.

In C, everything was passed by value, and everything was returned by value.
If you wanted to alter an object in the calling function, then you passed
its address. There was one other time, however, in C, where you passed the
object's address: when the object type was large and it would have been
more efficient to pass its address rather than passing the object by value.

As mysterious as references may be, they're still apart of our world, and
must obey the laws of our physics and so forth. If you have a scenario such
as:

struct PictureInfo {

unsigned width;
unsigned height;
unsigned colour_depth;

/* More members */
};

void Func(PictureInf o const &info)
{
/* Do stuff with the object */
}

Then the compiler will treat it as if you wrote:

void Func(PictureInf o const *const p)

For the most part, references are exactly like const pointers -- const
pointers which you don't have to dereference.

There's something special about "references to const" though. If you bind a
"reference to const" to an R-value, then an object is created which lives
until the reference goes out of scope. Writing the following:

{
int &r = 5;
}

is effectively like writing:

{
int const five = 5;
int &r = five;
}

>Also, I un derstand that "const T&" allows for polymorphism whereas "T"
will generate code cuttting.


Indeed. In general though, you should always be passing user-defined
objects by reference to const, rather than by value.

> On the former points, I am fairly confident... But I'm somewhat
confused on how the two influence conversions. For example, suppose I
define the following type:

class Real{
public:
Real(int)
Real(float);
Real(double);
Real(long double);
...
Real operator+(Real) ;
};

Can I now write the following?
Real x = 5.0;
Real y = x + 3;
//is above legal now if I don't define Real::operator+ (int)?


Question to Physics teacher:
"I have an apple in my hand; if I let go of it, will gravity pull it to
the ground?"

Answer from Physics teacher:
"Why are you asking *me* when you can try compile it with your own
compiler?"
Because not all compilers are conformant, and I have been having
difficulty getting it to work either way. Although, I submit, I have
been using a more complicated instance than the example given here.
>
>Now, suppose I change the declaration+def inition of
Real::operator +(Real) to Real::operator+ (const Real&), is the above
still legal? Or do I need to modify the above to the following?


Would it be legal if you passed its address? References are just a fancy
way of passing around addresses.
Yes, I understand that... Then I suppose I misstated the question.
>
The question is this:
Given the two definitions type::func(cons t type&) and type::func(type ),
does the compiler use different rules to match these? Given
type::type(int) and either type::func(cons t type&) or type::func(type ),
does the compiler accept type::func(5) in both cases? If not does it
accept it in any case?

Aug 17 '06 #3
"Frederick Gotham" <fg*******@SPAM .comwrote in message
news:ns******** ***********@new s.indigo.ie...
>
Question to Physics teacher:
"I have an apple in my hand; if I let go of it, will gravity pull it
to
the ground?"

Answer from Physics teacher:
"Why are you asking *me* when you can try compile it with your own
compiler?"
Because my compiler might accept non-standard code?
Would it be legal if you passed its address? References are just a fancy
way of passing around addresses.
References are just a way of renaming objects. That's all. They can be
implemented by passing around addresses, but that's no requirement. For
example:

void fn(int &x) { x = 2*x; }

This function would be horrible if implemented as pass-by-address, when x
could simply be passed in and out by value. The compiler is free to
implement the function this way, and it should.

--
Philip Potter

Aug 17 '06 #4
In article <ns************ *******@news.in digo.ie>,
Frederick Gotham <fg*******@SPAM .comwrote:
>In C++, references are "magical". The Standard says everything about how
they behave, but absolutely nothing about what they actually are.
This is true of many things though.
>In C, everything was passed by value,
And how are they passed now? :)

Anyway, in C array's are not passed by value.
>...
{
int &r = 5;
}

is effectively like writing:

{
int const five = 5;
int &r = five;
}
No, that's an error. Actually both forms are. You probably mean
const int &r
--
Greg Comeau / 20 years of Comeauity! Intel Mac Port now in alpha!
Comeau C/C++ ONLINE == http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Aug 17 '06 #5
Michael Safyan wrote:
Dear members of comp.lang.c++,
I am a little bit confused about the differences between constant
references and values. I understand that it is faster to use a constant
reference ("const T&") than a value ("T") since the former does not
require copying whereas the latter does, is that correct?
Not necessarily. If the copying is trivial, you may introduce
worse performance with the reference. For example, it's probably
a lose with any numeric or pointer type. Small POD classes probably
also may not be a win. However, when you've got something with a
large amount of internally-managed dynamic memory, you are right.
Using the original (read-only) rather than a copy is going to win.

Can I now write the following?
Real x = 5.0;
Real y = x + 3;
//is above legal now if I don't define Real::operator+ (int)?
Yes, because you have converting constructors to go from int to Real.
>
Now, suppose I change the declaration+def inition of
Real::operator+ (Real) to Real::operator+ (const Real&), is the above
still legal? Or do I need to modify the above to the following?
No problem, and this is specifically why you want to make it a
CONST reference. A non-const reference could not be bound to
the temporary converted value.
In short, can one convert an unnamed constant to a constant reference or
only to a value?
If it will convert to a value, it will convert to a const-reference.
Aug 17 '06 #6

Greg Comeau wrote:
In article <ns************ *******@news.in digo.ie>,
Frederick Gotham <fg*******@SPAM .comwrote:
In C++, references are "magical". The Standard says everything about how
they behave, but absolutely nothing about what they actually are.

This is true of many things though.
In C, everything was passed by value,

And how are they passed now? :)

Anyway, in C array's are not passed by value.
In C arrays are not passed at all. Arrays degrade to pointers any time
they are used as an r-value. The pointer is passed by value to the
function. Even when you use syntax such as:

void c(int arr[]);

arr is actually a pointer inside of 'c'. All the above syntax does is
inform the human reader that the input is expected to be an array. To
the compiler it means exactly the same thing as:

void c(int * arr);

Aug 17 '06 #7
Ron Natalie wrote:
Michael Safyan wrote:
>Dear members of comp.lang.c++,
I am a little bit confused about the differences between constant
references and values. I understand that it is faster to use a
constant reference ("const T&") than a value ("T") since the former
does not require copying whereas the latter does, is that correct?

Not necessarily. If the copying is trivial, you may introduce
worse performance with the reference. For example, it's probably
a lose with any numeric or pointer type. Small POD classes probably
also may not be a win. However, when you've got something with a
large amount of internally-managed dynamic memory, you are right.
Using the original (read-only) rather than a copy is going to win.

>Can I now write the following?
Real x = 5.0;
Real y = x + 3;
//is above legal now if I don't define Real::operator+ (int)?

Yes, because you have converting constructors to go from int to Real.
>>
Now, suppose I change the declaration+def inition of
Real::operator +(Real) to Real::operator+ (const Real&), is the above
still legal? Or do I need to modify the above to the following?

No problem, and this is specifically why you want to make it a
CONST reference. A non-const reference could not be bound to
the temporary converted value.
>In short, can one convert an unnamed constant to a constant reference
or only to a value?

If it will convert to a value, it will convert to a const-reference.
Thank you so much. That was exactly what I wanted to know.
Aug 17 '06 #8
In article <11************ **********@p79g 2000cwp.googleg roups.com>,
Noah Roberts <ro**********@g mail.comwrote:
>Greg Comeau wrote:
>In article <ns************ *******@news.in digo.ie>,
Frederick Gotham <fg*******@SPAM .comwrote:
>In C++, references are "magical". The Standard says everything about how
they behave, but absolutely nothing about what they actually are.

This is true of many things though.
>In C, everything was passed by value,

And how are they passed now? :)

Anyway, in C array's are not passed by value.

In C arrays are not passed at all.
In some cross-breeding of terms, actually more informally it's
boinks into the realm of 'pass by reference' which is not
about C++ references though some of the underlying machinery
may be similar, and which has the semantics your desribe.
--
Greg Comeau / 20 years of Comeauity! Intel Mac Port now in alpha!
Comeau C/C++ ONLINE == http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Aug 18 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
5056
by: Bolin | last post by:
Hi all, A question about smart pointers of constant objects. The problem is to convert from Ptr<T> to Ptr<const T>. I have look up and seen some answers to this question, but I guess I am too stupid to understand and make them work. E.g. I have read that boost's smart pointers are able to do this convertion, but the following code doesn't compile (VC++6.0):
19
2794
by: Christian Engström | last post by:
If you have a function that returns something by value, the gcc compiler (version 3.2.3 on Windows XP with MinGW) converts the returned value from the type you specify in the code, to the const version of that type. Is this a bug that is specific to gcc, or is it a flaw in the language specification that gcc diligently implements? For example, the below program produces the output Constant Mutable
39
3081
by: JKop | last post by:
Back when I read my first C++ book, I was given the following scenario: class Cheese { public: int number_of_holes; int colour;
11
2535
by: modemer | last post by:
If I define the following codes: void f(const MyClass & in) {cout << "f(const)\n";} void f(MyClass in) {cout<<"f()\n";} MyClass myclass; f(myclass); Compiler complain that it can't find the best match. Anyone could give a detail explanation in theory? Which one is good?
2
2355
by: Eric Lilja | last post by:
Hello, consider this complete program: #include <iostream> #include <string> using std::cout; using std::endl; using std::string; class Hanna {
4
6690
by: grizggg | last post by:
I have searched and not found an answer to this question. I ran upon the following statement in a *.cpp file in a member function: static const char * const pacz_HTMLContentTypeHeader = "Content-Type: text/html\r\n"; Why is the second const needed and what does it do? Thanks
10
3439
by: JurgenvonOerthel | last post by:
Consider the classes Base, Derived1 and Derived2. Both Derived1 and Derived2 derive publicly from Base. Given a 'const Base &input' I want to initialize a 'const Derived1 &output'. If the dynamic type of 'input' is Derived1, then 'output' should become a reference to 'input'. Otherwise 'output' should become a reference to the (temporary) result of the member function 'input.to_der1()' which returns a Derived1 object by value.
2
10116
by: wizofaus | last post by:
Given the following code: public class Test { static unsafe void StringManip(string data) { fixed (char* ps = data) ps = '$'; }
3
4093
by: George2 | last post by:
Hello everyone, I am debugging MSDN code from, http://msdn2.microsoft.com/en-us/library/0eestyah(VS.80).aspx here is my output, 1>main.cpp
0
9132
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9004
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8864
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7682
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5842
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4351
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4592
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3024
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2288
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.