In a C++ template with the generic type T, I can use
const T &
to get a reference to a constant T. However, if now T itself is a reference type (like e.g. T = int &), the above term resolves to
int &
and not to
const int &
which quite makes sense, since any reference itself is always constant. However, is there still a way to require a
const T &
if T itself is a reference type?
Edit: sample code to evaluate (g++ compiler):
template <typename T> class TemplateClass
{
public:
void foo(const T &bar) { }
};
int main()
{
TemplateClass<int &> x;
x.foo(0); // <-- compile error: no conversion from int to int&
return 0;
}
But const (int&) is a reference int& that is const , meaning that the reference itself cannot be modified.
Not just a copy; it is also a const copy. So you cannot modify it, invoke any non-const members from it, or pass it as a non-const parameter to any function. If you want a modifiable copy, lose the const decl on protos .
When we create our own copy constructor, we pass an object by reference and we generally pass it as a const reference. One reason for passing const reference is, we should use const in C++ wherever possible so that objects are not accidentally modified.
A const reference is actually a reference to const. A reference is inherently const, so when we say const reference, it is not a reference that can not be changed, rather it's a reference to const. Once a reference is bound to refer to an object, it can not be bound to refer to another object.
Remove the reference:
template<typename T>
void Test(const typename std::remove_reference<T>::type & param)
{
param = 20;
}
Now it works as expected.
You can always use template specialisation to implement a different version for any kind of reference:
template <typename T> struct X {
void foo(T const&);
};
template <typename T> struct X<T&> {
void foo(T const&);
};
Now, X<int>::foo
expects an int const&
and X<int&>::foo
expects an int const&
, too.
However, it is not entirely clear from your question what you are trying to do exactly.
Edit: My g++ version (4.6.1) does not complain without template specialisation for the following
int i = 7;
X<int&>(i);
While it does for
X<int&>(7);
Which is correct IMO, because you try to convert a temporary (7
) to a mutable reference (even if that is a reference to a const reference).
Edit 2: If you want to reduce duplicate code, then do not specialise your original class, but use this:
template <typename T> struct R {
typedef T& Ref;
typedef T const& ConstRef;
};
template <typename T> struct R<T&> {
typedef T& Ref;
typedef T const& ConstRef;
};
template<typename T> struct X {
void foo(typename R<T>::ConstRef x);
};
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