从VC++到GCC移植:谈两者的语法差异,该怎么处理

从VC++到GCC移植:谈两者的语法差异
类型引用
template   <class   T>
class     Foo
{
        typedef   T::SomeType   SomeType;
};
这段代码在VC++中一点问题也没有,但是GCC并不允许,因为它不知道T::SomeType是什么。你需要改为:

template   <class   T>
class     Foo
{
        typedef   typename   T::SomeType   SomeType;
};
通过typename   T::SomeType告诉GCC,SomeType是一个类型名,而不是其他东西。

当然,这种情况不只是出现在typedef中。例如:

template   <class   Container>
void   visit(const   Container&   cont)
{
        for   (Container::const_iterator   it   =   cont.begin();   it   !=   cont.end();   ++it)
                  ...
}
这里的Container::const_iterator同样需要改为typename   Container::const_iterator。

 

基类成员引用
template   <class   Base>
class   Foo   :   public   Base
{
public:
        void   foo()   {
                  base_func();
                  m_base_member   =   0;
        }
};
这段代码在VC++中同样没有问题,但是GCC中不能通过。因为GCC并不知道base_func,m_base_member是什么。对于这个问题,你可以有两种改法:

改法1:加上域作用符Base::
template   <class   Base>
class   Foo   :   public   Base
{
public:
        void   foo()   {
                  Base::base_func();
                  Base::m_base_member   =   0;
        }
};
改法2:使用using指示符
template   <class   Base>
class   Foo   :   public   Base
{
public:
        using   Base::base_func;
        using   Base::m_base_member;

        void   foo()   {
                  base_func();
                  m_base_member   =   0;
        }
};
这两种方法各有好处,在class   Foo中出现大量的Base::base_func、m_base_member的引用时,使用using是方便的。而如果只有一次,那么方法1显得简短。

 

交叉引用许可
class   SomeClass;

template   <class   T>
class   Foo
{
public:
          void   foo(SomeClass&   a)   {
                    a.some_func();
          }
          void   foo2()   {
                    SomeClass   a;
                    a.some_func();
          }
};

class   SomeClass
{
public:
            void   some_func()   {
                      ...
            }
};
由于VC++对模板函数的迟编译,因此,一个模板类不只是可以调用一个尚未出现的类成员函数(或者访问其成员变量),甚至可以定义其实例。这种语法对C++来说确实显得怪异。因为等到编译后面的SomeClass时,他又可以在其函数中定义class   Foo的实例,从而出现交叉引用的情况。这在非模板函数的情形下就算你用VC++亦难以做到。