2014-01-29 26 views
2

我在C++中實現某些特性時很困難,我試圖從互聯網上看幾個例子,但它仍然不想編譯。在C++中忽略了特質專精

我使用一個Term類,它包含一個Attribute,Operator,有時還有一個值。例如,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存儲將取決於這兩個屬性&運營商的價值,所以我用特徵來獲得合適的類型來存儲價值。

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

特徵對我來說是一個新概念,所以也許我犯了一些明顯的錯誤。如果有人有更好的方式或更簡單的方式來做到這一點,我也感興趣。

+0

從你的錯誤無關,你可能想從''AbstractTerm''公開繼承,也標誌着''布爾的eval(數據*)常量用''override''來確定它是否被覆蓋(如果它不能覆蓋,編譯器會報錯)。 –

回答

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