忽略了c ++中的traits特化

时间:2014-01-29 15:52:04

标签: c++ templates template-specialization traits

我在C ++中实现特征时遇到了一些困难,我试图从互联网上关注几个例子,但它仍然不想编译。

我使用Term类,其中包含AttributeOperator,有时还包含值。例如,age < 10color == red是(简单)术语。存在不同类型的属性或运算符,它们继承自类AttributeTermOperator。 由于term类的许多方法都取决于属性和运算符,因此这是一个模板类。为了简化术语的操作,我添加了一个抽象类: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;
};

我需要存储在term中的值取决于属性和属性。运算符,所以我使用traits来获取存储值的正确类型。

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;
};

但是,在eval方法中,当我使用VALUE_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*'
};

我收到错误:

error: request for member 'isEmpty' in '* pValue', 
which is of non-class type 'Term<NumericAttribute, 
TermOperatorExists>::VALUE_TYPE {aka int}. 

我无法弄清楚为什么它不使用专业化TermTraits<NumericAttribute, TermOperator>,因为TermOperatorExists继承自TermOperator

对我来说,特征是一个新概念,所以也许我犯了一些明显的错误。如果某人有更好的方法或更简单的方法来做到这一点,我也很感兴趣。

1 个答案:

答案 0 :(得分:0)

虽然TermOperatorExists继承自TermOperator,但这些类型不同,因此不会为TermOperatorExists调用模板专精化。您需要将TermOperatorExists显式转换为其基类才能获得名为。

的特化

示例:

#include <iostream>

using namespace std;

class base
{
};
class derrived: public base
{
};

class test
{
    public:
    template <class T> void print(T arg)
    {
        std::cout << "test" << std::endl;
    }
};

template <>
void test::print<base>(base arg)
{
    std::cout << "base specialiation" << std::endl;
};

int main()
{
   cout << "Hello World" << endl; 
   base b;
   derrived d;


   test t;
    t.print<int>(1);
    t.print(b);
    t.print(d);
    t.print(static_cast<base>(d));
   return 0;
}

输出:

Hello World
test
base specialiation
test
base specialiation