1

这部分与这个 SO question 有关

我有两个类,它们都是模板化的,例如:

class Base
{
public:
    template< class T > void operator=(T other)
    {
        //irrelevant
    }

    Derived toDerived()
    {
        Derived d;
        //do stuff;
        return d;
    }
};

class Derived: public Base
{
public:
    template< class T > void foo( T other )
    {
        //do stuff 
    }
};

如您所见,两者都是模板化的,并且在Base类函数内部我需要创建一个Derived. 当然,现在的方式我得到了一个错误Derived does not name a type。不幸的是,我不能只是 forward-declare Derived,因为它会导致另一个错误variable 'Derived d ' has initializer but incomplete type

从我上面提到的 SO 问题中,我了解到编译器需要了解所有模板参数才能正确前向声明它。但是很明显,我不能只是将Derived声明向上移动,因为它会导致完全相同的问题,反之亦然。

有没有办法做到这一点?

4

3 回答 3

4

这个问题与模板无关。您可以只使用前向声明Derived来编译声明Base::toDerived()并根据Derived Derived定义移动函数定义:

// Forward declaration of Derived
class Derived;

// Definition of Base
class Base
{
public:
   // Base::toDerived() declaration only
   Derived toDerived();
};

// Definition of Derived
class Derived: public Base
{
public:
...
};

// Base::toDerived() definition
inline Derived Base::toDerived()
{
   Derived d;
   // Do dirty things
   return d;
}
于 2012-09-28T06:05:36.790 回答
3
// Declare, but do not define
class Derived;

class Base {
public:    
    // Declare, but do not define
    // at this point Derived must be declared to be able
    // to use it in the return type
    Derived toDerived();
};

// Define
class Derived: public Base {
    // Rest of definition
};

// At this point Derived is defined

// Define
Derived Base::toDerived()
{
    // Implementation goes here
}
于 2012-09-28T06:05:32.080 回答
3

你可以做

class Derived;

class Base
{
public:
    template< class T > void operator=(T other)
    {
        //irrelevant
    }

    Derived toDerived();
};

class Derived: public Base
{
public:
    template< class T > void foo( T other )
    {
        //do stuff 
    }
};

Derived Base::toDerived()
{
    Derived d;
    //do stuff;
    return d;
}

如您所见,它与模板无关。

此外,这种设计根本感觉不对。

于 2012-09-28T06:06:33.327 回答