#c #templates
#c #шаблоны
Вопрос:
У меня есть следующее в заголовке ядра третьей стороны, который я бы предпочел не трогать:
template<typename Iterator_T>
struct Tree
{
template<typename Node_T>
struct TypedNode;
struct AbstractNode
{
AbstractNode(Iterator_T t)
{
...
}
template<typename Rule_T>
TypedNode<Rule_T>* NewChild()
{
TypedNode<Rule_T>* ret = new TypedNode<Rule_T>(this);
AddChild(ret);
return ret;
}
template<typename T>
TypedNode<T>* GetFirstTypedChild();
};
template<typename Node_T>
struct TypedNode : AbstractNode
{
...
};
template<typename Rule_T, typename ParserState_T>
void CreateNode(ParserState_Tamp; p)
{
current = current->template NewChild<Rule_T>();
}
};
template<typename Node_T>
struct TreeBuilder
{
Tree<Iterator_T> tree;
template<typename Rule_T>
void CreateNode()
{
tree.CreateNode<Rule_T>(*this);
}
};
и хотел бы добавить подкласс TypedNode в дерево с дополнительными методами и членами. Есть ли чистый способ сделать это без рефакторинга исходного кода? Я думаю, что суть проблемы заключается в:
TypedNode* ret = новый TypedNode(этот);
Похоже, что он мог бы использовать фабрику, возможно, специализируя создание экземпляра шаблона TypedNode и включая заголовок перед базовыми заголовками. Что-то вроде:
template<>
struct Tree<const char*>::TypedNode<SpecificRuleType>
{
...
};
Но это не удается, жалуясь на «слишком мало списков шаблонов-параметров». Возможно, что-то тривиальное, но мой <template-fu> немного заржавел :>(. Любые идеи будут оценены!
Ответ №1:
Оба Tree
и TypedNode
являются шаблонами, ваша специализация должна быть:
template<> // for Tree<...>
template<> // for TypedNode<...>
struct Tree<const char*>::TypedNode<SpecificRuleType>
{
...
};
Комментарии:
1. Еще раз.. время ожидания окна редактирования истекло. <enter> настаивает на отправке комментария в этом браузере! Спасибо — это помогло обойти ошибку. К сожалению, быстро выскочила другая жалоба на: current = current-> template newChild<Rule_T>(pos), в которой говорится, что он не может преобразовать дерево<const char*>::TypedNode<SpecificRuleType>* в дерево<const char*>::AbstractNode * в присваивании. TypedNode является подклассом AbstractNode, но, возможно, это связано с тем, что в первом объявлении TypedNode не указано, что он наследуется от AbstractNode.
2. Неважно.. существует альтернативный подход, который позволяет избежать всего этого шаблонного фуу. Даже если бы я заставил его работать, я подозреваю, что перенос его на другой компилятор может быть приключением, и проблема довольно тривиальна. Спасибо за вашу помощь!