我有以下代码,它不是用 gcc 编译的,但是用 MSVC 编译得很好。
class B;
class A
{
B *_parent;
public:
template <typename T>
void Do(T val)
{
_parent->DoB(val);
}
A(B *parent)
: _parent(parent)
{
}
};
class B : public A
{
public:
B()
: A(nullptr)
{
}
void DoB(int val)
{
cout << val << endl;
}
};
int main() {
B b;
A a(&b);
a.Do(10);
return 0;
}
编译错误如下:
prog.cpp: In member function ‘void A::Do(T)’:
prog.cpp:15:10: error: invalid use of incomplete type ‘class B’
_parent->DoB(val);
^~
prog.cpp:4:7: note: forward declaration of ‘class B’
class B;
^
根据类似的帖子,由于标准的第 14.6.9 段,gcc 的行为是正确的。但这是违反直觉的,因为模板应该只在使用的地方实例化。并且唯一的用法发生在所有类都被定义之后。
我的问题是这个问题的解决方法是什么?因为在这种情况下使用成员模板真的很方便。也许问题出在体系结构或其他方面?
最佳答案
您可以声明A
中依赖于B
的部分是已知的,但稍后定义它们。声明看起来像这样
class B;
class A
{
B *_parent;
public:
template <typename T> void Do(T val); /* (see below) */
A(B *parent) : _parent(parent) {}
};
然后是B
的定义
class B : public A { /* As before. */ };
最后定义缺失的部分
template <typename T> void A::Do(T val)
{
_parent->DoB(val); /* Fine, B is known. */
}
作为旁注,使用 gcc 8 编译的原始代码仅带有警告。
关于c++ - 未编译函数模板中使用的类的前向声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51476511/