f



References to const

Hi, I am reading C++ Primer but am having some difficulty understanding 
references to const. I am hoping that this turns out to be quite a 
simple topic and I find that I am only thinking it is complex.

I understand that a reference is simply another name for an object and 
that we can bind references to objects that are non const or const. 
Further a reference to const is unique in that it cannot be used to 
change the object to which the reference is bound.

My difficulty in understanding concerns the initialization rules for 
references to const.

There is a general rule in c++ (subject to two exceptions) which says 
that the type of a reference must match exactly the type of the object 
to which it refers when it is initialized. Now according to my book, one 
exception to this rule concerns a reference to const:

C++ Primer page 61 "..we can initialize a reference to const from any 
expression that can be converted to the type of the reference. In 
particular, we can bind a reference to const to a nonconst object, a 
literal, or a more general expression."

What is the reason for this exception?

Well reading on, the book does not (in my opinion) explain this section 
very well. I cannot understand what follows next and have quoted it 
verbatim in case you don't have the book:

"The easiest way to understand the difference in initialization rules is 
to consider what happens when we bind a reference to an object of a 
different type:

double dval = 3.14;
const int &ref = dval;

Here ref refers to an int. Operations on ref will be integer operations, 
but dval is a floating point number, not an integer. To ensure that the 
object to which ref is bound is an int, the compiler transforms this 
code into something like

const int temp = deval; // create a temporary const int from the double
const int &ref = temp; bind ref to that temporary

In this case, ref is bound to a temporary object. A temporary object is 
an unnamed object created by the compiler when it needs a place to store 
a result from evaluating an expression...

Now consider what could happen if this initialization were allowed but 
ref was not a const. If ref weren't const, we could assign to ref. Doing 
so would change the object to which ref is bound. That object is a 
temporary, not dval. The programmer who made ref refer to dval would 
probably expect that assigning to ref would change dval. After all, why 
assign to ref unless the intent is to change the object to which ref is 
bound? Because binding a reference to a temporary is almost surely not 
what the programmer intended, the language makes it illegal."

----
I have read this several times today and seem to be getting more 
confused each time I read it so will perhaps come back to it in the 
morning. I would really appreciate it if someone who has a clear 
understanding of this issue could explain this to me in a simple step by 
step manner! Why can a reference to const be bound to an object that 
does not match the reference type exactly? Why would anyone want to do 
this in real code? Alternatively, could you recommend any other text 
books or articles that might help me?


I think part of my problem is that I cannot see how this might apply to 
real code - it all seems very abstract. However,I have a feeling that 
this is a really *really* important basic topic that I need to grasp 
before moving on.

Best wishes


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Robert
7/29/2015 4:30:22 PM
comp.lang.c++.moderated 10738 articles. 1 followers. allnor (8509) is leader. Post Follow

8 Replies
545 Views

Similar Articles

[PageSpeed] 43

[Please do not mail me a copy of your followup]

Robert <rob1@invalid.net> spake the secret code
<vb9ux.54392$UI6.3334@fx45.am4> thusly:

>C++ Primer page 61 "..we can initialize a reference to const from any
>expression that can be converted to the type of the reference. In 
>particular, we can bind a reference to const to a nonconst object, a 
>literal, or a more general expression."
>
>What is the reason for this exception?

It means that you can have a function or method that accepts a parameter by
const reference and call that function or method with an instance of a
non-const object.

This is really the only way that it makes sense to use const references;
otherwise the only thing you could associate with a const reference would be
a const object and most objects change at *some* point in the program.

Consider the following function:

bool ends_with_foo(const std::string &text) {
    return text.size() >= 3U && text.substr(text.size()-3) == "foo"; }

This function is saying that it's parameter 'text' is obtained by a const
reference to std::string.  The const means we promise not to modify the
argument inside the function -- which is good because this function is
acting like a predicate and it shouldn't be changing the object under
inspection.

If we could only call 'ends_with_foo' on const strings, this would be
unfortunate, because we'd end up doing needless copies just to be able to
call this predicate.  The rule that allows a const reference to be
initialized from a non-const object makes the predicate useful in the
obvious way:

std::string ender{"I end with foo"};
std::string unender{"I end with bar"};
bool yes = ends_with_foo(ender);
bool no = ends_with_foo(unender);

Otherwise I'd have to get things into a constant string just to be able to
query it:

std::string ender{"I end with foo"};
const std::string const_ender{ender};
std::string unender{"I end with bar"};
const std::string const_unender{unender}; bool yes =
ends_with_foo(const_ender); bool no = ends_with_foo(const_unender);

--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
     The Computer Graphics Museum <http://computergraphicsmuseum.org>
         The Terminals Wiki <http://terminals.classiccmp.org>
  Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
legalize
7/29/2015 8:41:48 PM
On Wednesday, 29 July 2015 22:40:15 UTC+1, Robert  wrote:
> There is a general rule in c++ (subject to two exceptions) which says 
> that the type of a reference must match exactly the type of the object 
> to which it refers when it is initialized. Now according to my book, one 
> exception to this rule concerns a reference to const:
> 
> C++ Primer page 61 "..we can initialize a reference to const from any 
> expression that can be converted to the type of the reference. In 
> particular, we can bind a reference to const to a nonconst object, a 
> literal, or a more general expression."
> 
> What is the reason for this exception?

Because it is very useful, and is safe.  

It is safe because if I have a non-const object, and initialize a 
reference-to-const with it, then the fact I can't modify the object via the
reference-to-const is not very interesting.

It is useful because if I have a function that doesn't need to modify an
object, I can declare the function parameter as reference-to-const - but I
can still pass a non-const object to the function.


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Martin
7/30/2015 11:01:56 AM
{ as the only moderator currently active I assure you no reformatting
  of code in any post in the recent months has been undertaken. -mod }

[Please do not mail me a copy of your followup]

(Richard) legalize+jeeves@mail.xmission.com spake the secret code
<mpbj39$bau$1@news.xmission.com> thusly:

>bool ends_with_foo(const std::string &text) {
>    return text.size() >= 3U && text.substr(text.size()-3) == "foo"; }

I don't know who is reformatting my code; I certainly didn't post it
in this form.

I don't mind moderation, but I see no reason for moderators to
reformat my code to *their* personal taste.
-- 
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
     The Computer Graphics Museum <http://computergraphicsmuseum.org>
         The Terminals Wiki <http://terminals.classiccmp.org>
  Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
legalize
7/31/2015 7:12:24 AM
* Richard Thomson, on 31-Jul-15 3:12 PM:
>
> * Richard Thomson
> > bool ends_with_foo(const std::string &text) {
> >     return text.size() >= 3U && text.substr(text.size()-3) == "foo"; }
>
> I don't know who is reformatting my code; I certainly didn't post it
> in this form.
>
> I don't mind moderation, but I see no reason for moderators to
> reformat my code to *their* personal taste.

Re the moderation policy question:

This is a misunderstanding: the moderators (or moderator!, thanks Victor 
Bazarov for holding the fort) don't reformat code other than, sometimes, 
making it fit into reasonably short lines, e.g. 76 characters (*). But 
there are many possible causes of reformatting when you post on Usenet. 
I can /guess/ that the formatting change is that the right brace has 
been moved, that it was originally on a third line.

For clc++m the moderation process involves resending your posting with 
headers added, via an ordinary mail client, which can just Do Things. 
There is a possibility that your posting was sent, by your client 
software, with "flowed" format, and if a line ends with a space then in 
"flowed" format that indicates that it's part of a paragraph, i.e. the 
space is regarded as a line continuation. The moderator's editor can 
then automatically join up the line, without the moderator noticing at all.

There are much worse things that can happen, in particular with line 
lengths and encodings. When you look at the raw underlying text it's 
often no longer very recognizable, as it was in the old days, e.g. due 
to e-mail conventions like "quoted printable" sneaking their way into 
Usenet (not to mention HTML and base 64). And the tools employed no 
longer work easily at the raw text level, so, we just have to contend 
with what our imperfectly-smart tools do for us, and hope that at the 
human level we can still manage to communicate meaningfully. ;-)

Cheers & hth.,

- Alf, a currently not-active mod

Notes:
(*) The moderation guideline is, "If possible, fit your text in 70 
columns". The guidelines are available at the URL noted below.

-- 
Using Thunderbird as Usenet client, Eternal September as NNTP server.


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Alf
8/1/2015 7:32:12 AM
On Wednesday, July 29, 2015 at 5:40:15 PM UTC-4, Robert wrote:
> ...
> 
> C++ Primer page 61 "..we can initialize a reference to const from any 
> expression that can be converted to the type of the reference. In 
> particular, we can bind a reference to const to a nonconst object, a 
> literal, or a more general expression."
> 
> What is the reason for this exception?

The reason is that a reference is basically an alias to another
value/object.

    double dval = 3.14;
    double& rdval = dval;
    rdval = rdval * 2;  // dval has been changed to 6.28(*).

If you want a modify a value/object's converted representation, you
wouldn't use a reference but a converted value/object, like this:

    double dval = 3.14;
    int ival = dval;

Since ival is NOT a reference, a programmer wouldn't assume that
changing ival would change dval.

    int& rival = dval; //< this is illegal

The reasons that is illegal is because dval would have to create an
unnamed temporary which is considered a rvalue and cannot be modified.
Therefore you cannot bind it to a non-const reference.

    int const& const_rival = dval;

If const_rival happened to be an object, the life of the temporary
that is bound to it would be extended to the end of the enclosing
scope, otherwise, it would be free to be destroyed once it has been
used.  However, this is getting beyond the scope of your original
question.

(*) Please note that a double is a floating point number and as such
    you should never do a equal comparison due to rounding error of
    equivilant representations.  ALWAYS compare a floating point
    against an error range.


JAZ


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Jack
9/4/2015 7:53:48 AM
On Friday, 4 September 2015 14:00:16 UTC+1, Jack Adrian Zappa  wrote:
> (*) Please note that a double is a floating point number and as such
>     you should never do a equal comparison due to rounding error of
>     equivalent representations.  ALWAYS compare a floating point
>     against an error range.

I think that "ALWAYS" is too strong.  In your example (involving 2 * 3.14)
it
is correct, but I believe the following code is reasonable:
  double d = 2.0;
  double d2 = d * d;
  assert(d2 == 4.0);

(Note: The standard doesn't guarantee the assert won't fire, but it is
very, very, unlikely to do so.)


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Martin
9/11/2015 7:01:10 AM
On Friday, 11 September 2015 15:10:17 UTC+3, Martin Bonner  wrote:
> On Friday, 4 September 2015 14:00:16 UTC+1, Jack Adrian Zappa  wrote:
> > (*) Please note that a double is a floating point number and as such
> >     you should never do a equal comparison due to rounding error of
> >     equivalent representations.  ALWAYS compare a floating point
> >     against an error range.
> 
> I think that "ALWAYS" is too strong.  In your example (involving 2 * 3.14)
> it
> is correct, but I believe the following code is reasonable:
>   double d = 2.0;
>   double d2 = d * d;
>   assert(d2 == 4.0);

He didn't claim that floating point arithmetic always results
with slightly off results. It just happens frequently enough
to make 'operator==' unreliable in practice. People who want
to write reliable code must avoid unreliable constructs.

Your "reasonable" is also too strong. That code will be 
optimized to nothing on most compilers so it feels difficult
to reason why to write it. ;)

> 
> (Note: The standard doesn't guarantee the assert won't fire, but it is
> very, very, unlikely to do so.)

AFAIK even 'assert(d2 == 3.0);' is not required to fire on
conforming C++ implementation. Floating point is quite totally
implementation-defined.


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
ISO
9/11/2015 12:32:32 PM
On 09/11/2015 02:32 PM, �� Tiib wrote:
> 
> On Friday, 11 September 2015 15:10:17 UTC+3, Martin Bonner  wrote:
>> On Friday, 4 September 2015 14:00:16 UTC+1, Jack Adrian Zappa  wrote:
>>> (*) Please note that a double is a floating point number and as such
>>>     you should never do a equal comparison due to rounding error of
>>>     equivalent representations.  ALWAYS compare a floating point
>>>     against an error range.
>>
>> I think that "ALWAYS" is too strong.  In your example (involving 2 *
3.14)
>> it
>> is correct, but I believe the following code is reasonable:
>>   double d = 2.0;
>>   double d2 = d * d;
>>   assert(d2 == 4.0);
> 
> He didn't claim that floating point arithmetic always results
> with slightly off results. It just happens frequently enough
> to make 'operator==' unreliable in practice. People who want
> to write reliable code must avoid unreliable constructs.
> 
> Your "reasonable" is also too strong. That code will be 
> optimized to nothing on most compilers so it feels difficult
> to reason why to write it. ;)

Well, the assert was just a demonstration. In real-world code, the
assert() would be replaced by an if(), and might be widely separated
from the line which calculates d2.
The point is that real-world floating point implementations can produce
reliable results, so long as the final result and all intermediate steps
involve values that have the form of sufficiently small integers
multiplied by small positive or negative powers of two. It's not
entirely unreasonable to count on such things, even though the standard
doesn't provide any support for such assumptions.

>> (Note: The standard doesn't guarantee the assert won't fire, but it
is
>> very, very, unlikely to do so.)
> 
> AFAIK even 'assert(d2 == 3.0);' is not required to fire on
> conforming C++ implementation. Floating point is quite totally
> implementation-defined.

assert(DBL_MAX - DBL_MIN > DBL_MIN - DBL_MAX) is not required to
trigger, either. I'd be interested in knowing if there's any real-world
implementation where it doesn't.


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
James
9/12/2015 1:57:32 PM
Reply:

Similar Artilces:

non-const reference and const reference
Hello everyone, This is my understanding of non-const reference, const reference and their relationships with lvalue/rvalue. Please help to review whether it is correct and feel free to correct me. Thanks. 1. A const reference can be binded to a rvalue, for example, a temporary object. And the "life" of the temporary object is guaranteed to be extended and we can safely operate through the const-reference. 2. A non-const reference can not binded to a rvalue, I think the reason is rvalue is not addressable? And we can not change the rvalue through its reference? Are there any othe...

How to let C++ compiler raise a warning or error when a const is assigned to a const reference.
Hi, I have the following which has a bug (see the commented line). The one with the bug has the output of 10 -1073752704 The one without the bug has the output of 10 10 However, the compiler that I'm using can't generate any warning or error for this bug. I'm wondering if there is a option to select such that the compiler can tell this error? Thanks, Peng #include <iostream> class A{ public: A(const int a) : _a(a) { //should be: A(const int &a) : _a(a) { } void print() const { std::cout << _a << std::endl; } private: const ...

const references to references
Hi, I have been playing around with some experimental library that uses a proxy class to encapsulate a reference. The idea is that these have semantics as close to C++ references as possible (but it uses reference counting under the hood so there are no lifetime issues). All of the interesting methods of the proxy class are const, since the references are not reseatable. This is also consistent with ordinary references; "int& const" is not a valid type, but only because the 'const' is redundant. Anyway, it would be pointless to require a non-const proxy r...

Is it "reference to const" or "const reference"?
void funk(const int& X); How do you identify X, "reference to const" or "const reference", or does it matter? Is the semantics the same as C with pointers? Want to get it right, Joe [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] sweetiebentley@hotmail.com wrote: > void funk(const int& X); > > How do you identify X, "reference to const" or "const reference", or > does it matter? Is the semantics the same as C with pointers? > Want to get i...

given reference to non-const-qualified object, get reference to const-qualified object
/* Two questions: 1) Is there a way to do what I'm trying to do with eep? (Take a reference to a non-const-qualified object and get the reference to the const-qualified object.) 2) Is there a difference between tcConstRefOne and tcConstRefTwo? What is it?? */ template < typename txRef > struct cnEep { typedef const txRef tcConstRefOne; // no warning typedef txRef tcRef; typedef const tcRef tcConstRefTwo; // type qualifiers are meaningless in this declaration }; int main() { typedef cnEep < int & > tfEep; int vfA; // Surprisingly non-const-qualifi...

const correctness
I define this class: class foo { std::vector<int>data; public: int operator[](int n) { return data[n]; } int operator[](int n) const { return data[n]; } }; Now in my program I do: foo myFoo; int x = myFoo[123]; .... Should the const version of foo::operator[] be called? I think it should, but my compiler disagrees with me. What's the correct behavior? Why...? -- <\___/> / O O \ \_____/ FTB. http://www.topaz3d.com/ - New 3D editor! In article <7908dabe-5102-4669-bf68-6cd36bedd6a7@m74g2000hsh.googlegroups.com>, fungus <openglMYSOCKS@art...

const C g(); // const?
class C { int x; public: C() : x(0) {} void f(int); }; const C g(); // const? Is it reasonable to say, as a general guideline, a non-member function that returns a class type should *not* be declared *const* if the class has non-const member functions? Why? So that we can say g().f(); (This is a thought I had after reading a piece of Effective C++ Intro and Item 21.) [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] Marlene Miller wrote: > class C { > int x; > public: > C(...

jython and C-c C-c
How do I get C-c C-c to work with jython? I have the jpython command set to jython, and I can start the interpreter with C-C ! and then use C-c C-c, but this is rather frustrating. If I try to use C-c C-c without first starting the interpreter in another window I get wrong type argument: sequencep, jpython Thanks, Dave Cook ...

Better C/C++ Than C/C++?
I am looking for a good systems programming language that can be used instead of C/C++. My qualifications for the language are: * mature compiler(s) that produce native-code binaries (for Windows) * open source - preferable, but not 100% necessary Thanks, Kevin "Kevin Albrecht" <kevin@albrecht.net> writes: > I am looking for a good systems programming language > that can be used instead of C/C++. My qualifications > for the language are: > > * mature compiler(s) that produce native-code > binaries (for Windows) Ocaml, D, cyclone, Eiffel, Beta >...

[Q} Rationale behind C++ rule on copying temporary object to const reference
Hi, Can anyone explain the rationale behind the C++ standard rule [dcl.init.ref]/5, bullet 2, sub-bullet 1 (see also [class.temporary]/2) ? In short, what this rule says is that, when you pass a temporary object to a (member) function that expects a const reference, the temporary should be copy-constructible. To me, this is counter-intuitive. One of the reasons (I was taught) to use const references in a function's parameter list is to allow passing of temporary objects, because temporary objects are effectively const. This rule obviously forbids this use for non-copyable object...

reference to reference and constness problems with bind1st
T x; T foo(T, T); bind1st(ptr_fun(foo), x) creates a function object that takes an argument of type T const&. This does not work if T is already a reference type like int const&. So my first problem is with the &. My second problem is with the const. Why should bind1st change the constness of the second argument of the function�? I am currently using boost::bind instead, but I would rather not depend on boost for all my programs... Marc wrote: > > T x; > T foo(T, T); > bind1st(ptr_fun(foo), x) > > creates a function object that takes an argu...

What to return -- object, reference or const reference
After writing code in Java for sometime, one thing that I am not comfortable at all with C++ is the return type of an object. In java, i do not remember ever seeing a method return a final reference -- though a const is not equivalent to final, it is confusing when i see some methods returning a const reference. I initially assumed returning an object is same as returning a reference, because when i call the method as Myclass O1; O1 = func(); Does it matter if func() returns a reference, const reference or a Object, anyways the assignment operator is going to get called. But I am a bit c...

wxDesigner const int and c/c++
We have upgraded to wxDesigner 2.11 to build with wx2.5.3 This version replaces the #define IDs with const int. In c++ "const int" has file scope, so you can have ID_OK in lots of separate _wdr.h files so long as only one is included in each source file. But in c "const int" has global scope and so this would crash. We have a project which links both c++ files and c files in the same executable, compiling under linux with gcc/g++ we get errors from multiple definitions of "const int" - even though the _wdr.h are only included in .cpp files. Any...

const reference / rvalue reference overloads
{ Please replace tabs with spaces before posting. TIA., -mod/aps } Doesn't extensive use of rvalue references cause lots of overloads of functions (in particular creation functions and constructors)? It seems so to me. Lets consider this example: class Person { public: Person( const std::string& first_name, const std::string& last_name ) : m_first_name( first_name ), m_last_name( last_name ) { } const std::string& get_first_name() const { return m_first_name; } const std::string& get_last_name() const { return m_last_name;...

Any quick reference for the difference between C and C++
Hi, I have been using C++ a lot and I've almost forgot what syntax is support by C and what syntax is support by C++? My feeling is that C++ gives programmer much flexibility. And the code is more localized in C++ than C, which mean changes won't propogate far away in C++ code. By reusing through inherence and overloading, a lot of code can be saved. But I have to use C for some reason. Is there any programming paradigm in C, which can give me as much advantage that C++ as possilbe? Is there any quick reference which can tell me what C++ syntax is forbidden in C? Best wishes, Peng ...

Web resources about - References to const - comp.lang.c++.moderated

Wikipedia talk:Reference desk/Guidelines/Medical advice - Wikipedia, the free encyclopedia
I disagree with this implication that this section of the guideline represents the consensus. If you look at the last few years of discussion ...

Microsoft dismisses iPad Pro as “a companion device” and references old Steve Jobs stylus quote
... to be a companion device.” Laycock also said that “at one point in time, Apple declared that if there’s a stylus, that’s failure” – a reference ...

Can you spot these classic film references hidden in Pixar movies?
The animators at Pixar definitely love to throw in allusions to some of their favorite movies in their own films. Vimeo user Jorge Luengo Ruiz ...

10 hidden references to classic films in your favorite Pixar movies
... Madrid, told BuzzFeed that he noticed a ton of allusions in "Toy Story 3" and was inspired to make a video highlighting the cinematic references ...

See The Classic Movie References Found In Pixar's Greatest Films
... all well aware of just how clever Pixar movies are. These emotionally engaging stories are full of intricate themes and crammed with references ...

Worst passwords of 2015: Star Wars references sneak onto list
Enough with "123456" already! SplashData's annual list of the worst passwords in use includes some old favorites and some new sci-fi-inspired ...

Zootopia Trailer Adds a Godfather Reference to Disney Film - Collider
Watch a new trailer for the Disney animated movie Zootopia, which takes place in a world inhabited by talking animals and features Jason Bateman ...

Hillary Clinton Ends Democratic Debate With A Star Wars Reference
The other day, President Obama ended his White House press conference with a reference to The [...]

Review: Klipsch X20i Reference In-Ear Headphones
These Klipsch X20i Reference In-Ear Headphones are pretty darn fantastic, and worth every penny.`

O’Malley References How Old Clinton And Sanders Are While Explaining His ISIS Strategy
O’Malley References How Old Clinton And Sanders Are While Explaining His ISIS Strategy

Resources last updated: 1/25/2016 10:02:40 AM