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
Remove the reference:
template<typename T>
void Test(const typename std::remove_reference<T>::type & param)
{
param = 20;
}
Now it works as expected.
I have encountered the very same problem. It seems that the '&' type conversion operator binds stronger than the 'const' qualifier. So when we have this code:
template<class t>
void fun(const t i)
{
}
fun<int&>();
the function ends up with type void(int&), not the expected void(const int&).
To solve this problem, I have defined this template:
template<class t> struct constify { typedef t type; };
template<class t> struct constify<t&> { typedef const t& type; };
Now define your function as:
template<class t>
void fun(typename constify<t>::type i)
{
}
fun<int&>();
The instantiated function will have the type void(const int&), as needed.
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);
};