In MSVC 2008, I have the following code:
class Foo { // Be a little smarter about deriving the vertex type, to save the user some typing. template<typename Vertex> inline void drawVertices( Elements vCount, RenPrim primitiveType, PixMaterial *mtl, Vertex const *vertices) { this->drawVertices(vCount, primitiveType, mtl, vertices, Vertex::VertexType); } virtual void drawVertices( Elements vCount, RenPrim primitiveType, PixMaterial *mtl, void const *vertices, uint vertexType) = 0; };
I use it something like:
struct RenFlexibleVertexPc { enum { VertexType = RenVbufVertexComponentsPc }; float x; float y; float z; GraVideoRgba8 c; // Video format, not external! }; PixMaterial *material; struct Pc : RenFlexibleVertexPc { void set(Triple t, uint cl) { x = (float)t.x_; y = (float)t.y_; z = (float)t.z_; c = cl; } } vpc[4]; ... Foo *renderer; renderer->drawVertices(4, RenPrimTriangleFan, material, vpc);
This works fine in MSVC 2008 SP1. However, GCC (3.4 and 4.1,2) throws a ‘no matching function for call to function’ error, apparently not seeing the template when there is a non-template function with more arguments.
Is GCC broken, or is my code broken, and if so, why?
There is no problem with overloading or inheritance:
Works correctly. On the other hand, the smallest example I can find that exhibits your problem does not have inheritance or overloading:
Note that if
struct Bis defined in a namespace (whether it’s an unnamed namespace, or a completely different namespace, or the global namespace) instead of insidemain()that this compiles without error.I don’t know enough of the standard to say if this is a bug, but it appears to be one. I’ve gone ahead and reported it to the GCC bug database.And here’s your answer from the GCC developers (from the link above): ‘Local classes cannot be template arguments.’
So the code is broken. Not that it’s a bad idea. In fact, C++0x removes this restriction.
I noticed the line
And since
RenFlexibleVertexPcis not a local class this makes sense. HoweverPcis a local class/struct, so it is not allowed.