【发布时间】:2021-12-25 20:12:23
【问题描述】:
这是对a question I asked a few weeks ago 的后续处理,其中的答案是,在模板中使用仅在模板实例化时完成但在当时不完整的类型是格式错误的,不需要诊断其定义。
我的后续问题是,在不完整类型本身依赖于模板参数的情况下,这仍然适用吗?因为它似乎不是。以下在 Godbolt 上的所有编译器中编译,即使 foo::do_stuff() 使用 foo_wrapper::value() 仅给出类模板 foo_wrapper 最终将存在的前向声明。
#include <iostream>
template<typename T>
class foo_wrapper;
template<typename T>
class foo {
foo_wrapper<T>& parent_;
public:
foo(foo_wrapper<T>& wrapped) : parent_(wrapped)
{}
void do_stuff() {
std::cout << "do stuff " << parent_.value() << "\n";
}
};
template<typename T>
class foo_wrapper {
foo<T> foo_;
T value_;
public:
foo_wrapper(T n) :
foo_(*this),
value_(n)
{}
void do_stuff() {
foo_.do_stuff();
}
T value() const {
return value_;
}
};
int main()
{
foo_wrapper<int> fw(42);
fw.do_stuff();
}
【问题讨论】:
-
您的代码不同,因为您访问的是模板类
foo_wrapper。链接的答案给出了“由于不依赖于模板参数的构造,紧随其定义的模板的假设实例化将是格式错误的”。在这种情况下,代码取决于模板参数。 -
在您的代码中,模板
foo能够使用尚未定义的foo_wrapper,因为您只使用了引用。虽然尚不清楚该类型的具体细节,但编译器知道引用将是指针,因此它们的大小将用于传递和存储。这对foo来说已经足够了。