I have some hard time implementing traits in C++, I tried to follow several examples from the internet but it still doesn't want to compile.
I use a Term
class, which contains an Attribute
, an Operator
and sometimes a value. For example, age < 10
or color == red
are (simple) terms. Different kinds of attributes or operators exists, that inherits from classes Attribute
or TermOperator
.
Since a lot of methods of the term
class will depend on the attribute and the operator, this is a template class. In order to simplify the manipulation of terms, I added an abstract class : AbstractTerm
class AbstractTerm {
protected:
Attribute* pAttribute;
TermOperator* pOperator;
public:
virtual bool eval(Data *) const = 0;
};
template <typename ATT, typename OP>
class Term : AbstractTerm {
typedef typename TermTraits<ATT,OP>::type VALUE_TYPE;
private:
typename TermTraits<ATT,OP>::type value;
public:
bool eval(Data *) const;
};
The value I need to store in term
will depend on both attribute & operator, so I use traits to obtain the right type to store the value.
template < typename ATT, typename OP>
struct TermTraits
{
typedef int type;
};
template <>
struct TermTraits<ListAttribute, TermOperator>
{
typedef ListValue type;
};
template <>
struct TermTraits<NumericAttribute, TermOperator>
{
typedef NumericIntValue type;
};
However, in the eval
method when I use VALUE_TYPE
I don't get the right type
template <> bool Term<NumericAttribute, TermOperatorEquals>::eval(Data _data) const {
// VALUE_TYPE is a int, but it should be a NumericIntValue
VALUE_TYPE *pValue = data->getValue<VALUE_TYPE>(this->pAttribute->getId());
return !pValue->isEmpty && (this->value == pValue->value); // I get compilation errors here because pValue is a int* and not a 'NumericIntValue*'
};
I get the error:
error: request for member 'isEmpty' in '* pValue',
which is of non-class type 'Term<NumericAttribute,
TermOperatorExists>::VALUE_TYPE {aka int}.
I can't figure out why it doesn't use the specialisation TermTraits<NumericAttribute, TermOperator>
, since TermOperatorExists
inherits from TermOperator
.
Traits are a new concept to me, so maybe I made some obvious mistakes. If someone has a better way or simpler way to do this I'm also interested.