When compiling (Microsoft Visual C++ 2005 Express) this piece of code:
struct A
{
template< typename T > static A Foo( void ) { return A(); }
struct S
{
template< typename T > static S GetInstance( void )
{
S Result;
Result.m_funcFoo = &A::Foo< T >;
return Result;
}
A ( *m_funcFoo )( void );
};
};
int main(int argc, char* argv[])
{
A::S::GetInstance< int >();
}
I get a C2440 error:
‘=’: cannot convert from ‘A (__cdecl *)(void)’ to ‘A (__cdecl *)(void)’
That doesn’t make sense to me. The two types named in the error text are obviously the same.
Also, when changing Foo‘s return value to int, there is no such error.
Is it a bug or am I doing something wrong?
EDIT :
So, if it’s a bug, does anyone know how to solve this? Maybe by using casts? I need this code to compile…
It’s a compiler bug. VC++ is doing something very weird.
For example, this generates a very different error message:
And this works:
Clearly it’s getting confused by the name
A, which should refer to the base class.Adding a typedef didn’t help, neither does a forward declaration of
struct A, neither does qualifying the name as::Aorstruct A.Oddly enough, VC++7 compiles it fine.
Workaround: Changing it like this:
inverts the result, now VC++8 compiles ok and VC++7 generates the same error message.
I think there’s a type identity issue between an incomplete type and the same type after completion.
All tests run using the Dinkumware Multi-Compiler Test Tool