По вдохновению Матье Брухера и Jarod42, я попытаюсь использовать представление компилятора, чтобы объяснить это, поправьте меня, если я ошибаюсь.
Как упоминал Jarod42:
(внутренний) TB - это шаблон.
A1 - это тип.
TB - это тип (с T2 = A1)
и в силу того факта, что шаблон будет создан при его использовании, строка B<A1<B>> bt;
- это место, где шаблон попадает в определенный тип.Итак, A1<B>
- это тип, давайте сделаем реальный класс с именем A1_IMPL, то есть A1<B>--A1_IMPL
, B<A1<B>>
- это тип, давайте создадим класс с именем B_IMPL, то есть B<A1<B>>--B<A1_IMPL>--B_IMPL
.Таким образом, B_IMPL выглядит следующим образом:
class B_IMPL {
public:
B_IMPL() : t1_(*this) {}
void Test() {
t1_.Test();
}
void Print() const {
std::cout << "test\n";
}
private:
A1_IMPL t1_;
};
A1 будет выглядеть следующим образом:
class A1_IMPL {
public:
explicit A1_IMPL(const B<A1<B>> &b) : b_(b) {}
void Test() {
b_.Print();
}
private:
const B<A1<B>> &b_;
};
, который еще не закончен, поскольку A1<B>--A1_IMPL
, B<A1<B>>--B<A1_IMPL>--B_IMPL
, конечный A1_IMPL будет выглядеть следующим образомэто:
class A1_IMPL {
public:
explicit A1_IMPL(const B_IMPL &b) : b_(b) {}
void Test() {
b_.Print();
}
private:
const B_IMPL &b_;
};
шаблона больше нет.