#include <iostream>
template <typename T>
struct ref_exp{
typedef T value_type;
typedef value_type& reference_type;
typedef const reference_type const_reference_type;
ref_exp(value_type data): _data(data){}
const_reference_type data() const {return _data;}
private:
value_type _data;
};
int main(){
ref_exp<int> exp1(2);
std::cout << exp1.data() << std::endl;
return 0;
}
The above code doesn't compile
ref.cpp: In member function ‘T& ref_exp<T>::data() const [with T = int]’:
ref.cpp:17: instantiated from here
ref.cpp:10: error: invalid initialization of reference of type ‘int&’ from expression of type ‘const int’
But If I replace const_reference_type data() const
with const value_type& data() const
it works. Also If I replace typedef const reference_type const_reference_type
with typedef const value_type& const_reference_type
it compiles
Your const_reference_type
typedef does not do what you think:
typedef const reference_type const_reference_type;
const_reference_type
is int& const
- that is, the entire type reference_type
has const
applied to it - and a const
reference cannot exist, so you get int&
. You are not getting a const int&
as you are expecting.
As you've noted, the fix here is to do:
typedef const value_type& const_reference_type;
The tip here is to not think of typedef
as just a find-and-replace of type names, because it doesn't behave that way.
const reference_type
is indicating that the reference is const, not that the referenced object is const.
typedef int &int_ref; // int_ref is a reference to a non-const int
typedef const int_ref int_ref_const;
// int_ref_const is a const reference to a non-const int
The const qualifier in the second case is basically a no-op, since references are implicitly const.
Think about a similar case with pointers:
typedef int *int_ptr; // int_ptr is a pointer to a non-const int
typedef const int_ptr int_ptr_const;
// int_ptr_const is a const pointer to a non-const int.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With