考虑一个示例,其中方法是纯虚拟的,采用模板类型的参数(从外部类型注入),并且该模板类型是本地类型(在函数体中定义)。这种情况会导致 g++ 下的编译时错误。诚然,这是一个非常极端的案例,但它确实源自真实代码。这是一个可编译、可重现的示例:
#include <cstdio>
template<typename T>
struct Outer
{
struct InnerBase
{
virtual void foo(T const&) = 0;
virtual void bar(T const&) { };
};
struct InnerDerived : public InnerBase
{
void foo(T const&) override { std::printf("virtual call foo() worked\n"); }
void bar(T const&) override { std::printf("virtual call bar() worked\n"); }
};
InnerBase* inner;
Outer() : inner(new InnerDerived()) { }
};
struct NonLocalStruct { };
int main()
{
struct LocalStruct { };
Outer<NonLocalStruct> a;
Outer<LocalStruct> b;
a.inner->foo(NonLocalStruct()); // fine
a.inner->bar(NonLocalStruct()); // fine
b.inner->foo(LocalStruct()); // causes error
b.inner->bar(LocalStruct()); // fine
return 0;
}
有人可以解释为什么这会导致编译错误吗?为什么它适用于非本地类型而不适用于本地类型?为什么非纯虚方法有效但纯虚方法无效?
我正在使用带有 -std=c++11 的 g++ 4.8.1(我也在 VS2010 中尝试过这个示例,它编译并运行没有错误)。
g ++的确切错误是:
test.cpp:8:16:错误:'void Outer::InnerBase::foo(const T&) [with T = main()::LocalStruct]',使用本地类型'const main()::LocalStruct'声明,已使用但从未定义 [-fpermissive]