const reference typedef compile error:

  • Follow


Can someone please explain why the following fails to compile?

//----------------

typedef int               value_type;
typedef value_type&       reference;
typedef const value_type& const_reference;

struct woot
{
        //OK
        const value_type& foo() const { return value_; };

        //OK
        const_reference bar() const { return value_; };

        //ERR
        const reference waldo() const { return value_; };

        value_type value_;
};

int main()
{}

//----------------

This is the error in gcc 3.4.6:

typedef.cpp: In member function `value_type& woot::waldo() const':
typedef.cpp:16: error: invalid initialization of reference of type
'value_type&' from expression of type 'const value_type'

-Thanks!


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

0
Reply smith7005 1/2/2008 6:11:11 PM

smith7005 写道:
> Can someone please explain why the following fails to compile?
> 
> //----------------
> 
> typedef int               value_type;
> typedef value_type&       reference;
> typedef const value_type& const_reference;
> 
> struct woot
> {
>         //OK
>         const value_type& foo() const { return value_; };
> 
>         //OK
>         const_reference bar() const { return value_; };
> 
>         //ERR
>         const reference waldo() const { return value_; };
> 
>         value_type value_;
> };
> 
> int main()
> {}
> 
> //----------------
> 
> This is the error in gcc 3.4.6:
> 
> typedef.cpp: In member function `value_type& woot::waldo() const':
> typedef.cpp:16: error: invalid initialization of reference of type
> 'value_type&' from expression of type 'const value_type'
> 
> -Thanks!
> 
> 
Firstly, "const reference" just like "value_type& const", and the inner 
const was omited, so the real type of "const reference" is "value_type&".
int const non-static member function, the type of this pointer is "const 
struct* const", and the type of its member "value_" is "const 
value_type", by qulification conversion rules, you can not do it!


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

0
Reply cpplife 1/3/2008 5:24:17 PM


On Jan 3, 5:11 am, smith7005 <smith7...@yahoo.com> wrote:
> Can someone please explain why the following fails to compile?
>
> //----------------
>
> typedef int               value_type;
> typedef value_type&       reference;
> typedef const value_type& const_reference;
>
>...
>         //ERR
>         const reference waldo() const { return value_; };
>
>         value_type value_;
> ...

This is due to the meaning of "const reference" in your code. To avoid
confusion between the word reference and the type reference in your
code, let me rewrite the code segment as below:

typedef value_type& ref;
typedef const value_type& const_ref;

Here const_ref is a reference to const value_type. Here const applies
not to the reference but what is referred.

However, when you say

const ref x;

const applied to ref, the reference rather than what is referred. By
definition, all references are const (you can reassign references
ever).

So in your case the function waldo returns a (redundant const)
reference to (non const) value_type. Of course it is not allowed
inside a const function.

To understand the situation even better, try pointers instead of
references:

typedef int               value_type;
typedef value_type*       ptr;
typedef const value_type* const_ptr;

struct woot
{
        const value_type* foo() const { return &value_; };

        const_ptr bar() const { return &value_; };

        const ptr waldo() const { return &value_; };

        value_type value_;

};

It is fairly obvious why the body of waldo() is erroneous.

Thiru

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

0
Reply Thiruvalluvan 1/3/2008 5:27:46 PM

smith7005 <smith7005@yahoo.com> wrote in news:96b1f201-2bb8-4a6f-bb24-
ffc6408777b0@h11g2000prf.googlegroups.com:

> Can someone please explain why the following fails to compile?
> 
> //----------------
> 
> typedef int               value_type;
> typedef value_type&       reference;
> typedef const value_type& const_reference;
> 
> struct woot
> {
>         //OK
>         const value_type& foo() const { return value_; };
> 
>         //OK
>         const_reference bar() const { return value_; };
> 
>         //ERR
>         const reference waldo() const { return value_; };
> 
>         value_type value_;
> };
> 
> int main()
> {}
> 
> //----------------
> 
> This is the error in gcc 3.4.6:
> 
> typedef.cpp: In member function `value_type& woot::waldo() const':
> typedef.cpp:16: error: invalid initialization of reference of type
> 'value_type&' from expression of type 'const value_type'
> 
> -Thanks!
> 
> 

In 8.3.2/1 ([dcl.ref]/1) it says that cv qualifiers are ill-formed for 
references unless they are introduced via a typedef (as you have done) 
in which case, they are dropped.  So, you have the equivalent of:

value_type& waldo() const {return value_; }

So, since value_ is a const and the reference is to non-const you get an 
error.

I have a question though.  What did you think it would do?  Even if the 
const qualifier weren't dropped, you would have the equivalent of:

value_type& const waldo() const ...

Basically a const reference (rather than a reference to const) which is 
also ill-formed for which some compilers will just issue a warning, but 
you are still left with a reference to a non-const being initialized 
with a const which is a not allowed.

Hope that helps some.

joe


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

0
Reply Joe 1/3/2008 5:27:47 PM

On 3 Jan., 01:11, smith7005 <smith7...@yahoo.com> wrote:
> Can someone please explain why the following fails to compile?
>
> //----------------
>
> typedef int               value_type;
> typedef value_type&       reference;
> typedef const value_type& const_reference;

Note that cv-qualifications cannot be applied to a
reference itself, so the last typedef const_reference
just means "reference to const value_type".

> struct woot
> {
>         //OK
>         const value_type& foo() const { return value_; };
>
>         //OK
>         const_reference bar() const { return value_; };
>
>         //ERR
>         const reference waldo() const { return value_; };

This is indeed ill-formed code. The combined construction
'const reference' does *not* mean a reference to a *const*
value_type, see [dcl.ref]/1:

"[..] Cv-qualified references are ill-formed except
when the cv-qualifiers are introduced through the use
of a typedef (7.1.3) or of a template type argument
(14.3), in which case the cv-qualifiers are ignored.[..]"

So the above declaration is equivalent to

reference waldo() const { return value_; }

which is illformed, because a const member function
must not return a mutable reference to a (non-reference)
non-static data member.

> This is the error in gcc 3.4.6:
>
> typedef.cpp: In member function `value_type& woot::waldo() const':
> typedef.cpp:16: error: invalid initialization of reference of type
> 'value_type&' from expression of type 'const value_type'

gcc rightly rejects this code.

HTH & Greetings from Bremen,

Daniel Kr�gler


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

0
Reply ISO 1/3/2008 5:30:31 PM

smith7005 ha scritto:
> Can someone please explain why the following fails to compile?
> 
> //----------------
> 
> typedef int               value_type;
> typedef value_type&       reference;
> typedef const value_type& const_reference;
> 
> struct woot
> {
>         //OK
>         const value_type& foo() const { return value_; };
> 
>         //OK
>         const_reference bar() const { return value_; };
> 
>         //ERR
>         const reference waldo() const { return value_; };
> 
>         value_type value_;
> };
> 
> int main()
> {}
> 
> //----------------
> 
> This is the error in gcc 3.4.6:
> 
> typedef.cpp: In member function `value_type& woot::waldo() const':
> typedef.cpp:16: error: invalid initialization of reference of type
> 'value_type&' from expression of type 'const value_type'
> 

A "reference" is a /reference to int/. Right? Then a "const reference"
should be /const reference to int/. Notice the big difference with
"const_reference" which is instead a /reference to const int/: the const
applies to reference in one case and to int in the other case!

I say "should be" above, because top cv-qualifiers are ignored on
references, so the type of "const reference" is actually /reference to
int/.

The error occurs because value_, which an lvalue of type const int for
our purposes, can be bound to /reference to const int/ but cannot be
bound to a /reference to (non-const) int/.

HTH,

Ganesh

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

0
Reply Alberto 1/3/2008 5:30:33 PM

On Jan 2, 7:11 pm, smith7005 <smith7...@yahoo.com> wrote:
> Can someone please explain why the following fails to compile?
>
> //----------------
>
> typedef int               value_type;
> typedef value_type&       reference;
> typedef const value_type& const_reference;
>
> struct woot
> {
>         //OK
>         const value_type& foo() const { return value_; };
>
>         //OK
>         const_reference bar() const { return value_; };
>
>         //ERR
>         const reference waldo() const { return value_; };
>
>         value_type value_;
>
> };
>
> int main()
> {}
>
> //----------------
>
> This is the error in gcc 3.4.6:
>
> typedef.cpp: In member function `value_type& woot::waldo() const':
> typedef.cpp:16: error: invalid initialization of reference of type
> 'value_type&' from expression of type 'const value_type'
>
> -Thanks!
>
> --
>       [ Seehttp://www.gotw.ca/resources/clcm.htmfor info about ]
>       [ comp.lang.c++.moderated.    First time posters: Do this! ]

section [8.3.2] 'References' of the standard covers this situation.
[Perhaps someone else can throw a little insight...i make a lousy
lawyer]

It basicly says that if you have a declaration that looks like this:

 typedef int& Ref;
 const Ref r = 99; // is ill-formed
                   // non-const reference initialized with rvalue

such CV-qualified references are ill-formed *except* when these are
introduced through typedefines or a template type arguement, in which
case the qualifiers are ignored (1). The type of r is
reference_to_integer, not const_reference_to_integer.

Incidentally, You might consider doing it with a template. Since a
reference to your private parts makes sense, waldo() is no longer a
const member function. You can also test the statement (1) in the
standard about ignoring the const qualifier.

#include <iostream>

template < typename value_type >
struct test
{
private:
  value_type value_;
  typedef value_type& reference;
  typedef const value_type& const_reference;
  // read (1) above, const would be ignored
  // typedef const reference& const_reference;
public:
  // ctors
  test(const value_type t) : value_(t) { }
  test(const test& copy)
  {
    value_ = copy.value_;
  }
  // member functions
  const value_type& foo() const { return value_; };
  reference waldo() { return value_; }; // ERR
  const_reference bar() const { return value_; };
};

int main()
{
  test< int > instance(99);
  std::cout << instance.foo() << std::endl;
  std::cout << instance.bar() << std::endl;
  int& ref = instance.waldo();
  ref = 55;
  std::cout << instance.waldo() << std::endl;
}

/*
99
99
55
*/

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

0
Reply Salt_Peter 1/3/2008 5:30:34 PM

smith7005 wrote:
> typedef int               value_type;
> typedef value_type&       reference;
> typedef const value_type& const_reference;

>         //ERR
>         const reference waldo() const { return value_; };

There is no such thing as a const reference, references are always constant.
There are references-to-const though, but that is something different.
Here, the 'const' applies to the reference type, but as I said that makes
no sense. Please also make sure you read the FAQ, it explains the
differences between e.g. pointer-to-const and const pointer.

> invalid initialization of reference of type 
> 'value_type&' from expression of type 'const value_type'

Note that GCC seems to be ignoring this. The only thing it's complaining
about is that the const memberfunction is trying to return a
reference-to-nonconst member.

Uli


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

0
Reply Ulrich 1/3/2008 5:35:33 PM

smith7005 wrote:
> Can someone please explain why the following fails to compile?
> 
> //----------------
> 
> typedef int               value_type;
> typedef value_type&       reference;
> typedef const value_type& const_reference;
> 
> struct woot
> {
>         //OK
>         const value_type& foo() const { return value_; };
> 
>         //OK
>         const_reference bar() const { return value_; };
> 
>         //ERR
>         const reference waldo() const { return value_; };
           ^^^^^^^^^^^^^^
I guess you mean "const_reference"
as "const reference" means "int& const" which is illformed, reference 
has no constness, as it already none-mutable.

PS: no ";" after "}" when you define a function.

> 
>         value_type value_;
> };
> 
> int main()
> {}
> 
> //----------------
> 
> This is the error in gcc 3.4.6:
> 
> typedef.cpp: In member function `value_type& woot::waldo() const':
> typedef.cpp:16: error: invalid initialization of reference of type
> 'value_type&' from expression of type 'const value_type'
> 
> -Thanks!
> 
> 

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

0
Reply Barry 1/3/2008 5:36:50 PM

smith7005 wrote, On 3.1.2008 1:11:
> Can someone please explain why the following fails to compile?
> 
> //----------------
> 
> typedef int               value_type;
> typedef value_type&       reference;
> typedef const value_type& const_reference;
> 
> struct woot
> {
>         //OK
>         const value_type& foo() const { return value_; };
> 
>         //OK
>         const_reference bar() const { return value_; };
> 
>         //ERR
>         const reference waldo() const { return value_; };
Here const reference is not what you think it is.

> 
>         value_type value_;
> };
> 
> int main()
> {}
> 
> //----------------
> 
> This is the error in gcc 3.4.6:
> 
> typedef.cpp: In member function `value_type& woot::waldo() const':
> typedef.cpp:16: error: invalid initialization of reference of type
> 'value_type&' from expression of type 'const value_type'
> 
> -Thanks!
> 
> 
>From Comeaus online test drive:

Comeau C/C++ 4.3.9 (Mar 27 2007 17:24:47) for ONLINE_EVALUATION_BETA1
Copyright 1988-2007 Comeau Computing.  All rights reserved.
MODE:strict errors C++ C++0x_extensions

"ComeauTest.c", line 14: warning: type qualifiers are meaningless in this
          declaration
          const reference waldo() const { return value_; };
          ^

"ComeauTest.c", line 14: error: qualifiers dropped in binding reference of type
          "reference" to initializer of type "const value_type"
          const reference waldo() const { return value_; };
                                                 ^

1 error detected in the compilation of "ComeauTest.c".


-- 
VH

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

0
Reply Vaclav 1/3/2008 7:30:19 PM

9 Replies
494 Views

(page loaded in 0.623 seconds)

Similiar Articles:













7/21/2012 4:39:03 AM


Reply: