//----------------
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! ]
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
> 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
> //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
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
PS: no ";" after "}" when you define a function.
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
*/
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
>
> 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