2011-12-23 23 views
11

(のMicrosoft Visual C++ 2005のExpressの)コードのこの作品コンパイル:タイプxからタイプxに変換できませんか?

'=': cannot convert from 'A (__cdecl *)(void)' to 'A (__cdecl *)(void)'

私には意味がありません。

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

私はC2440エラーが発生します。エラーテキストに指定された2つのタイプは明らかに同じです。 また、Fooの戻り値をintに変更すると、そのようなエラーはありません。

これはバグですか、何か間違っていますか?

編集: だから、これはバグだと誰かがこれを解決する方法を知っていますか?たぶんキャストを使用することによって?私はこのコードをコンパイルする必要があります...

+4

これはバグ![....] –

+0

最初は、A(*(void))*はA(A :: *)(void)とは違うので、そのようにはできませんでした。 – Griwes

答えて

4

これはコンパイラのバグです。 VC++は非常に奇妙なことをやっています。

例えば、これは非常に異なるエラーメッセージを生成:

struct A 
{ 
    template< typename T > static struct 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); 
    }; 
}; 

sourceFile.cpp(5) : error C3856: 'A::Foo': class is not a class template 

をそして、これは動作します:

struct X {}; 

struct A 
{ 
    template< typename T > static X Foo(void) { return X(); } 
    struct S 
    { 
     template< typename T > static S GetInstance(void) 
     { 
      S Result; 
      Result.m_funcFoo = &A::Foo<T>; 
      return Result; 
     } 
     X (*m_funcFoo)(void); 
    }; 
}; 

は明らかにそれが基底クラスを参照する必要があります名前A、によって混乱です。

typedefを追加すると助けになりませんでした。struct Aの順方向宣言も、::Aまたはstruct Aの修飾もしません。

奇妙なことに、VC++ 7はそれをうまくコンパイルします。

回避策:はこのようにそれを変更する:

struct A 
{ 
    template< typename T > static A Foo(void) { return A(); } 

    struct S; 
}; 

struct A::S 
{ 
    template< typename T > static S GetInstance(void) 
    { 
     S Result; 
     Result.m_funcFoo = &A::Foo<T>; 
     return Result; 
    } 
    A (*m_funcFoo)(void); 
}; 

は結果を反転させ、今VC++ 8は、[OK]をコンパイルし、VC++ 7は、同じエラーメッセージを生成します。

私は、完成後に不完全な型と同じ型の間に型の識別の問題があると思います。

すべてのテストは、私がダウンして問題を追跡しようとしましたが、今ではこの奇妙なエラーを生成するテンプレートの機能またはネストされた構造体を持っている必要もないように思えるDinkumware Multi-Compiler Test Tool

1

コンパイラのバグかどうかわかりませんが、少なくともmsdnに記載されています。私は手元に2005コンパイラを持っていませんが、VS2010は、このようにそれを書いた場合、あなたのコードをコンパイル

struct A 
{ 
    template< typename T > static A Foo(void) { return A(); } 
    struct S 
    { 
     A (*m_funcFoo)(void);  

     template< typename T > static S GetInstance(void); 
    }; 
}; 

template< typename T > 
A::S A::S::GetInstance(void) 
{ 
    S Result; 
    Result.m_funcFoo = &A::Foo<T>; 
    return Result; 
} 
+0

ああ、MSDNのリンクはドイツ語です。 – fefe

+0

@fefeこれ以上はありません – AakashM

+0

@mkaes実際に 'A :: S :: GetInstance'をインスタンス化しましたか?私はVS2005とVS2010の両方であなたのコードをテストしました - それはまだ同じエラーです。 – Baltram

0

を使用して実行します。

struct A 
{ 
    typedef A (* SimpleFuncPtr)(void); 
    static void Foo(void) 
    { 
     SimpleFuncPtr func1 = 0;  // Ok. 
     SimpleFuncPtr func2 = func1; // Ok. 
     A (* func3)(void) = func1; // C2440 on both VS2005 and VS2010 
    } 
}; 

上記のコードを見ると、実際にはコンパイラのバグ(私の意見では)であることが明らかです。

+0

問題は不完全な型であり、mkaesによって提供されるリンクに記述されています(つまり、型が関数ポインタ定義時に不完全であるため、コンパイラはフル型が定義されたときに後でオーバーライドされる特定の呼び出し規約を選択します) ) –

関連する問題