Consider an example where a method is pure virtual, takes a parameter of a templated type (injected from an outer type), and that templated type is a local type (defined in a function body). This scenario causes a compile-time error under g++. Admittedly, this is quite a corner case, but it does originate from real code. Here's a compilable, reproducible example:
#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;
}
Can someone explain why this causes a compile error? Why does it work with non-local types but not local ones? Why do non-pure virtual methods work but not pure ones?
I'm using g++ 4.8.1 with -std=c++11 (I've also tried this example in VS2010 and it compiles and runs without errors).
The exact error from g++ is:
test.cpp:8:16: error: 'void Outer::InnerBase::foo(const T&) [with T = main()::LocalStruct]', declared using local type 'const main()::LocalStruct', is used but never defined [-fpermissive]