2009-04-09 13 views
0

、私は次のコードを持っている:これはMSVCで正常に動作GCCがテンプレート以外の機能を見つけられないのはなぜですか? ( "へ...呼び出しに該当する機能")MSVC 2008年

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); 

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; 
}; 

を私はそれのようなものを使用2008 SP1。しかし、GCC(3.4と4.1,2)は、関数呼び出しのための関数が一致しないため、より多くの引数を持つ非テンプレート関数がある場合、テンプレートを見ていないように見えます。

GCCは壊れていますか、またはコードが壊れていますか?その場合、なぜですか?

+0

は、コンパイルエラーが発生したコードを示します –

答えて

1

はありません。

#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()の内部です。

これはバグだとは言えませんが、それは1つのようです。私は先に進み、 reported it to the GCC bug database


そして、ここでは、(上記のリンクから)GCCの開発者からのあなたの答えだ:「ローカルクラスはテンプレート引数にすることはできません。」

コードが壊れています。 Not that it's a bad idea。実際、C++ 0xではこの制限が解除されています。

私は明示的にキャストVPC場合、コードは

(RenFlexibleVertexPc *)にGCCで動作し、RenFlexibleVertexPcがローカルクラスではないので、これは理にかなっていることをライン

注意に気づきました。しかし、Pcはローカルクラス/構造体なので、許可されません。

+0

これは素晴らしい答えでした。ありがとう!評判を持つ誰かがそれを投票してくれることを願っています。 私はちょうど将来生きようとしていると思います... –

0

VertexTypeの定義は、すでにコード(enum)にあります。要素は符号なしlongです。コードが(RenFlexibleVertexPc *)に明示的にキャストする場合、コードがGCCで動作することに注意してください。

structの4の型のオブジェクトを渡す理由は? RenFlexibleVertexPcとは何ですか? drawVerticesの最後の引数は、Vertexオブジェクトへの定数ポインタか、Vertexから派生したクラスのオブジェクトへのconst*のいずれかです。

Foo *renderer; 
renderer->drawVertices(4, RenPrimTriangleFan, material, vpc); 

初期化されていないポインタで関数を呼び出しています。私はこれが実際のコードではないことを願っています。

#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()); 
} 
正しく動作

:\の過負荷や継承に問題は

+0

もちろん、実際のコードでは初期化されていません。 "..."部分に注意してください。 VertexTypeの定義はすでにコード(列挙型)にあります。 要素は符号なしlongです。 vpcを(RenFlexibleVertexPc *)に明示的にキャストすると、このコードはGCCで動作することに注意してください。 –

+0

'...'はFoo * rendererの前です。 – dirkgently

1

@OP:テンプレートパラメータを指定することは有効なアプローチです。ピートの追加が

renderer->drawVertices<RenFlexibleVertexPc>(4, RenPrimTriangleFan, material, vpc); 

、あなたのコードはまた、AppleのGCC 4.0.1でコンパイルしたので、私はあなたの投稿コードはそれが問題を引き起こしている欠けている何かがあると思います。

@Max:あなたのソースのGCCの治療は標準です。構造体Bはmain()のローカルなので、main():: B :: print()はmain()の外側では見えません。あなたが知っているように、main()の外側でBの定義を動かしてコンパイルします。

+0

ありがとう、私は正直にそれを知らなかった。しかし、構造体Pc(すなわちvpc [4]変数)が関数で定義されており、関数の外でその定義を移動することで問題が解決されることに気付くでしょう。コードをコンパイルする。 –

+0

元の投稿の12行目のように「元のコード」と同じようなものを使っています:... struct Pc:RenFlexibleVertexPc {...} vpc [4]; " –

+0

これは、OPの投稿に欠けていたものでした。 struct Pcの定義は関数のローカルなのだとは言えませんでした(インデントはヒントであったはずです)。 – outis

関連する問題