Синтаксис объявления шаблона: template<class B>
(или, что эквивалентно, template<typename B>
).
Также имеется круговая ссылка: Base
ссылки MyOperation
(тип возврата и внутри функции operate
). Таким образом, MyOperation
необходимо будет определить до Base
.
Но MyOperation
также ссылки Base
(базовый класс).
Для базового класса и для использования внутри функции требуется полное определение. Но для возвращаемого типа достаточно неполного типа. Так MyOperation
необходимо будет предопределенные до того Base
, как:
template<class B> class MyOperation;
И кроме того, operate()
должен быть определен (не декларируется) за пределами class Base { ... }
, после определения MyOperation
. Правильный код будет выглядеть так:
// pre-declaration of MyOperation
template<class B> class MyOperation;
// definition of Base class
class Base {
public:
// declaration of Base::operate member function
// MyOperation<Base> is incomplete type here
MyOperation<Base> operate(Base x);
};
// definition of MyOperation class template
template<class B>
class MyOperation : public Base{
public:
B b;
MyOperation(B b_){ b = b_; }
};
// definition ofBase::operate member function
inline MyOperation<Base> Base::operate(Base x) {
return MyOperation<Base>(x);
}
Base::operate
должен быть рядным, если определение находится в заголовочном файле, в противном случае будет несколько символами линкера, если заголовок включен несколько исходных файлами.
Если это не встроенный (лучше, если это большая функция), то определение должно идти в исходном файле.
Является ли этот 'template (класс B)' правильным синтаксисом? – nbro
Компилятор должен показать вам строку. Обычно, если ошибка упоминает синтаксис, вы испортили синтаксис. Здесь у вас есть шаблон (класс B) ', когда он должен быть' template '. Может быть, это ваш псевдокод, иначе я бы опубликовал этот ответ. –
TankorSmash
'Base' не может _see_' MyOperation', потому что он определен _after_ 'Base'. –