Как работать с классами, которые зависят друг от друга и имеют элементы шаблона?

Это частично связано с этот ТАК вопрос.

У меня есть два класса, оба они шаблонные, например:

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, К сожалению, я не могу просто объявить Derived, потому что это приведет к другой ошибке variable 'Derived d ' has initializer but incomplete type,

Из вопроса SO, который я упомянул выше, я понимаю, что компилятор должен знать обо всех параметрах шаблона, чтобы иметь возможность правильно объявить его вперед. Но, очевидно, я не могу просто двигаться Derived объявление, потому что это приведет к точно такой же проблеме, только наоборот.

Есть ли способ сделать это?

1

Решение

// 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
}
3

Другие решения

Эта проблема не имеет ничего с шаблонами. Вы можете просто использовать предварительную декларацию 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;
}
4

Ты можешь сделать

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

Как видите, это не имеет ничего общего с шаблонами.

Кроме того, этот дизайн просто не чувствует себя хорошо.

3
По вопросам рекламы [email protected]