在MSVC 2008中,我有以下代码:
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;
};
我用的是:
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);
这在MSVC 2008 SP1中运行良好。但是,GCC(3.4和4.1,2)会抛出“没有匹配的函数调用函数”错误,当存在具有更多参数的非模板函数时,显然没有看到模板。
GCC是否被破坏,或者我的代码是否被破坏,如果是,为什么?
答案 0 :(得分:1)
重载或继承没有问题:
#include <iostream>
#include <memory>
namespace {
struct A {
virtual void f()
{
std::cout<<"inside A's f()\n";
}
template <typename T> void f(T t)
{
std::cout<<T::i<<'\t';
this->f();
}
};
struct B : A {
void f()
{
std::cout<<"hello\t";
A::f();
}
};
struct C {
static const unsigned int i = 5;
};
struct D {
enum { i = 6 };
};
}
int main()
{
std::auto_ptr<A> b(new B());
b->f(C());
b->f(D());
}
正常工作。另一方面,我能找到的最能展示问题的例子没有继承或重载:
#include <iostream>
namespace {
struct A {
template<class C> void print(C c)
{
c.print();
}
};
}
int main()
{
struct B {
void print()
{
std::cout << "whee!\n";
}
};
A a;
B b;
a.print(b);
}
请注意,如果在命名空间中定义struct B
(无论是未命名的命名空间,还是完全不同的命名空间,还是全局命名空间),而不是在main()
内部,则编译时没有错误。
我不知道该标准是否足够,如果这是一个bug,但它似乎是一个。我继续前进reported it to the GCC bug database。
以下是GCC开发人员的回答(来自上面的链接):“本地类不能是模板参数。”
因此代码被破坏了。 Not that it's a bad idea。实际上,C ++ 0x删除了这个限制。
我注意到了这一行
请注意,如果我明确地将vpc转换为(RenFlexibleVertexPc *)
,则代码在GCC中有效
由于RenFlexibleVertexPc
不是本地类,这是有道理的。但是Pc
是本地类/结构,因此不允许使用。
答案 1 :(得分:1)
@OP:指定模板参数是一种有效的方法。
renderer->drawVertices<RenFlexibleVertexPc>(4, RenPrimTriangleFan, material, vpc);
随着Pete的增加,你的代码也编译在Apple的GCC 4.0.1上,所以我怀疑你发布的代码丢失了导致问题的原因。
@Max:GCC对您的来源的处理是标准的。结构B是main()的本地,所以B(因此main():: B :: print())在main()之外是不可见的。您可能已经意识到,将B的定义移到main()之外,它将进行编译。
答案 2 :(得分:0)
,则代码在GCC中有效
VertexType
的定义已经在代码中(枚举)。元素是无符号长。请注意,如果我明确地将vpc转换为(RenFlexibleVertexPc *
)
如果它是枚举为什么要传递struct类型数组4的对象?什么是RenFlexibleVertexPc
? drawVertices
的最后一个参数应该是指向Vertex
对象的常量指针,或const*
指向从Vertex
派生的类的对象。
Foo *renderer;
renderer->drawVertices(4, RenPrimTriangleFan, material, vpc);
您正在调用未初始化指针上的函数。我希望这不是真正的代码。 \