Взаимодействие с шаблоном класса

Я действительно уверен, что ответ на мою проблему можно найти в одной из ранее созданных тем. В частности, где и почему я должен поставить ключевые слова "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, что угодно). Считайте это подсказкой использования.

Другие вопросы по тегам