Взаимодействие с шаблоном класса
Я действительно уверен, что ответ на мою проблему можно найти в одной из ранее созданных тем. В частности, где и почему я должен поставить ключевые слова "template" и "typename"? который имеет отличное объяснение неоднозначности шаблон / имя типа. Однако я в растерянности, потому что на самом деле я не могу расширить концепцию на мой код, который представляет собой шаблоны классов, взаимодействующие друг с другом.
В этой теме я вижу ту же ошибку, что и в своем коде. Почему ответ для определения typedef, используя A<B>
где B - класс, в отличие от A<T>
где T - шаблонное имя, которое мы на самом деле хотим получить.
Тем не менее, я пробовал эти варианты безрезультатно. Вот код Спасибо за помощь.
#include "testTemplateA.h"
template<typename A>
class testTemplateB {
public:
// none of these work
typedef testTemplateA<A> templateType;
typedef typename testTemplateA<A> templateType;
typedef typename testTemplateA<testTemplateB> templateType;
testTemplateB(templateType& TA) {}
~testTemplateB(void) {}
};
#include "testTemplateB.h"
template<typename A>
class testTemplateA
{
public:
testTemplateA(void) {}
~testTemplateA(void) {}
void callUponB(void) {
testTemplateB<A> g = testTemplateB<A>(this);
}
};
2 ответа
Это больше похоже на проблему циклической зависимости, чем на проблему синтаксиса шаблона. Пока вы можете определить один класс с другим неполным, вы можете сделать что-то вроде:
// Begin testTemplateA.h
#ifndef TEST_TEMPLATE_A_H
#define TEST_TEMPLATE_A_H
template<typename A>
class testTemplateA
{
public:
testTemplateA(void) {}
~testTemplateA(void) {}
void callUponB(void); // Can't be defined here!
};
#include "testTemplateB.h"
template<typename A>
void testTemplateA<A>::callUponB(void) {
testTemplateB<A> g = testTemplateB<A>(this);
}
#endif
// End testTemplateA.h
// Begin testTemplateB.h
// Yes, the include is outside the define guard.
#include "testTemplateA.h"
#ifndef TEST_TEMPLATE_B_H
#define TEST_TEMPLATE_B_H
template<typename A>
class testTemplateB {
public:
typedef testTemplateA<A> templateType;
testTemplateB(templateType& TA) {}
~testTemplateB(void) {}
};
#endif
// End testTemplateB.h
Если исходный файл содержит только testTemplateA.h, он увидит определение шаблона класса для testTemplateA
затем включите все содержимое testTemplateB.h, затем просмотрите определения членов в testTemplateA.h, которые зависят от testTemplateB
, Если исходный файл содержит только testTemplateB.h, он немедленно начнется с testTemplateA.h, который по-прежнему будет содержать testTemplateB.h в середине и получит те же результаты. Если исходный файл включает оба в любом порядке, второй не будет иметь никакого эффекта, так как оба уже были включены.
Вам нужно только typename
Ключевое слово, как это перед именем, включая по крайней мере один ::
маркер.
Еще одна вещь: ваш конструктор testTemplateB(templateType& TA);
ожидает ссылку, но ваше заявление testTemplateB<A> g = testTemplateB<A>(this);
передает значение указателя this
,
Проблема здесь
typedef testTemplateA<A> templateType;
Вы создаете шаблон класса, используя Class Template
template<typename A>
class testTemplateA
При создании шаблонного класса вам нужно указать фактический тип. Так и должно быть,
typedef testTemplateA<< testTemplateB<int >> templateType;
Рекомендуется использовать "класс", если ожидается, что T всегда будет классом, с "typename", если ожидаются другие типы (int, char*, float, что угодно). Считайте это подсказкой использования.