2012-12-21 269 views
-3

下面的代码编译时错误信息:模板和类型名称

@> g++ test.cpp 
    test.cpp: In member function 'void testit<E>::print()': 
    test.cpp:79: error: 'COL' is not a class or namespace 
    test.cpp:83: error: expected `;' before 'b2' 

如果我使用COL ::列;要访问静态成员,它不会成功编译。而是通过SelectColumn :: SELECT_COLS :: columns访问静态成员;会好的!

struct AllColumns 
{ 
    static const char columns[]; 
}; 
const char AllColumns::columns[] = "*"; 

struct MemoryColumns 
{ 
    static const char columns[]; 
}; 
const char MemoryColumns::columns[] = "data,data_expire_time"; 

template<typename E> 
struct SelectColumn 
{ 
public: 
    typedef unsigned BIGT; 
    typedef AllColumns SELECT_COLS; 
}; 

template<> 
struct SelectColumn<int> 
{ 
public: 
    typedef int BIGT; 
    typedef MemoryColumns SELECT_COLS; 
}; 

template<typename E> 
class testit 
{ 
public: 
    typename SelectColumn<E>::SELECT_COLS COL; 
    typename SelectColumn<E>::BIGT BIG; 

    void print() 
    { 
     string str_a = COL::columns; //compile error here! 
     string str_b = SelectColumn<E>::SELECT_COLS::columns; // OK 

     BIG b2 = 10; //compile error here! 
       typename SelectColumn<E>::BIGT b = 12; // OK 
    } 
}; 

如何解决它,如果我想使用COL ::列? 谢谢!

+0

如果您确实想通过您的类的实例访问静态成员,请注意这是一种糟糕的风格,因为读者可能会猜测它不是静态的。为了使你的代码*自我记录*,总是使用'type :: name'语法访问静态变量,而不是'instance.name'。 – leemes

回答

3
typename SelectColumn<E>::SELECT_COLS COL; 

是一个变量声明,而不是一个类型。 (变量的名称是COL,类型为typename SelectColumn<E>::SELECT_COLS

也许你的意思是说

typedef typename SelectColumn<E>::SELECT_COLS COL; 
+0

谢谢,我误解了班级中的typename的含义。 – SILENCE

0

COL是一个对象,而不是一个类型的,因此你必须说COL.columns到accees它的成员。

+0

'columns'是一个静态成员。虽然编写'COL.columns'在语法上是正确的,读者可能会认为它访问了一个实例变量,所以它应该被认为是* bad style *。 – leemes

1
typename SelectColumn<E>::SELECT_COLS COL; 

这里使用typename不是语法来使COLSelectColumn<E>::SELECT_COLS的别名,但要告诉解析器该标识符SELECT_COLS是一种类型的,而不是变量。

str_a = COL::columns; 

为什么你在这条线得到一个错误的原因,是因为你试图访问使用错误的语法COL对象的成员数据。