This question is related to my last one. I am trying to solve the problem using traits<T> and traits<T*>. Please consider the following code.
template<typename T>
struct traits
{
typedef const T& const_reference;
};
template<typename T>
struct traits<T*>
{
typedef const T const_reference;
};
template<typename T>
class test
{
public:
typedef typename traits<T>::const_reference const_reference;
test() {}
const_reference value() const {
return f;
}
private:
T f;
};
int main()
{
const test<foo*> t;
const foo* f = t.value(); // error here. cannot convert ‘const foo’ to ‘const foo*’ in initialization
return 0;
}
So it looks like compiler is not considering the traits specialization for pointers and taking return type of value() as const foo rather than const foo*. What am I doing wrong here?
Any help would be great!
The specialization is being used.
traits<foo*>::const_referenceisconst foo. If you want it to be a pointer, use:With this,
traits<foo*>::const_referencewill beconst foo*.Note that the use of
Tin thetraits<T*>specialization is completely separate from the T in thetraitstemplate. You could rename it:and you’ll have the same specialization. It makes more sense if you’ve experience in functional programming.
To start, think of the
template <typename ...>as introducing an abstraction, rather like a function abstracts out a value. It’s like turninginto:
where
ltakes the place of[1,2,3]. We can callsumsfrom another function that itself has a formal parameter namedl:sumsq‘s “l” has nothing to do withsum‘s “l”.With templates, we abstract type names rather than values. That is, we turn:
into:
Now consider a non-template specialization:
Here there are no template parameters for the specialization, but you can think of
traits<double*>as applying atraitstemplate to adouble*. Abstract out thedoubleand you have:Here the
Tis a parameter for the specialization, not the base template.