Reputation: 200
I have a template
and I have the methods T get(int i)
and set(int i, T val)
. I have to make traits class which change not behavior but the arguements which set
and get
have.
template<typename T,int Roz>
class Wektor{
public:
T tab[Roz];
T get(int i)
{
return tab[i];
}
void set(T val,int i)
{
tab[i]=val;
}
}
So the traits class have to change the get and set. If T is int or double we gets parametr by copy int
int get(int i);
void set(int val,int i);
double
double get(int i);
void set(double val,int i);
for others types:
T* get(int i);
void set(T* val,int i);
That we must do in traits not by specialization of template.
So I write tratis like this:
template<typename T,int Roz>
class traitsWektor
{
public:
T tab[Roz];
T get(int i)
{
return tab[i];
}
void set(T val,int i)
{
tab[i]=val;
}
}
So here I stuck. I think i should make
template<typename T, int Roz>
class Wektor : public traitsWektor<T,Roz>
But i am not sure is that right and is still tratis.
Upvotes: 0
Views: 289
Reputation: 18905
I am not sure how you want to implement set(T*,int)
. But for get
you might want to try this
template<typename T, size_t Roz>
class Wektor
{
public:
template<typename U=T>
typename std::enable_if<std::is_arithmetic<U>::value, U>::type
Get(size_t n)
{
return tab[n];
}
template<typename U=T>
typename std::enable_if<!std::is_arithmetic<U>::value, U*>::type
Get(size_t n)
{
return &tab[n];
}
T tab[Roz];
};
Upvotes: 0
Reputation: 24576
You should separate the class template (Wektor) and the parameter type deduction:
template <class T>
struct WektorParamTraits {
typedef T const& type;
//or if you might have different types as getter return type and setter arg
typedef T const& getterReturn;
typedef T const& setterArg;
};
In that case, T is the "default" type for your getter/setter arguments. Specialize it for any type you need. The class definition now should look like follows:
template<typename T,int Roz>
class Wektor{
T tab[Roz]; //make member variables private
public:
typename WektorParamTraits<T>::getterReturn get(int i) //const?
{
return tab[i];
}
void set(typename WektorParamTraits<T>::setterArg val,int i)
{
tab[i]=val;
}
};
Update: as was noted in the comments, you might need to define other implementations for get and set e.g. if your return type is a pointer. There are several different approaches to do that:
tab[i]
and the argument/return value.std::enable_if
with std::is_pointer
and whatever else is needed to disable one of them.Approach 2 would be very verbose and hard to read. Approach 1 would be verbose as well, and since you would delegate nearly everything except the array definition to that traits class, you could as well use approach 3 since that is not too far away.
Upvotes: 4
Reputation: 144
I think this template may help you:
template<typename T>
class traits
{
public:
typedef T * result;
};
template<>
class traits<int>
{
public:
typedef int result;
};
template<>
class traits<double>
{
public:
typedef double result;
};
traits<int>::result; // is int.
traits<char>::result; // is char *.
Upvotes: 0