6

ClangでコンパイルするためにMSVC用に記述されたコードを移植しようとしています。ただし、いくつかのテンプレート関数を見つけるのに問題があるようです。これが私に問題を与えている構造体の定義の一部です:

template< typename T > struct FixedVector
{
    T * ptr;
    size_t count;

    typedef T value_type;

    FixedVector():ptr(0),count(0) {}
    ~FixedVector()
    {
        DeleteArr(ptr); // Error message appears here
        count=0;
    }
// ...
}

このDeleteArr(ptr)関数は、次のように後で定義される関数を参照します。

template< typename T > inline void DeleteArr( T *& ptr )
{
    delete[] ptr;
    ptr = NULL;
}

これは私が示された行に表示されるエラーメッセージです:

error: call to function 'DeleteArr' that is neither visible in the template definition nor found by argument-dependent lookup

(Xcodeでの)エラーの完全なドロップダウンリストを見ると、次のメッセージがリストの下部にあります。

'DeleteArr' should be declared prior to the call site or in an associated namespace of one of its arguments.

このメッセージをクリックすると、上記のようにDeleteArr()関数の定義が表示されます。

これは明らかにMSVCで正常にコンパイルされており、ClangとMSVCの違いを見てみると、これは、使用する前にこのような関数を定義する必要がないMSVCの癖によるものです。どこかの定義。そこで、 Clangのドキュメントでこのエラーメッセージを調べました(関連部分は「テンプレートでの非修飾ルックアップ」というタイトルの下にあります)。テンプレート定義の前に前方宣言を追加することを提案しました。だから私はこれを次の定義の上に追加しましたFixedVector

template< typename T > inline void DeleteArr( T *& ptr );

ただし、このエラーメッセージはまだ表示されており、エラーメッセージの最後のビット(「呼び出しサイトの前に宣言する必要がある」ビット)は、関数の実際の定義を示しています。誰かが何が問題なのか知っていますか?これがMSVCでどのように有効であるかについては、私はまったく考えがありません。また、エラーメッセージは関数の定義を見つけることができるのに、なぜそれが見つからないと言っているのですか?

更新:コメントのアドバイスで、テンプレートの上で宣言した場所にDeleteArr()の実装を追加しました。これにより、同じエラーが発生するようです。私は今本当に困惑しています。

4

2 に答える 2

8

の宣言は、DeleteArrに利用可能である必要がありますFixedVector。つまり、前者の定義は、後者が使用する前に行う必要があります。これは、MSVCが2フェーズルックアップを正しく実装できなかったことに関連している可能性があります。

于 2012-09-26T10:12:51.440 に答える
1

最初にDeleteArrを定義します

template< typename T > inline void DeleteArr( T *& ptr )
    {
        delete[] ptr;
        ptr = NULL;
    }

次に、fixedvectorを定義します

template< typename T > struct FixedVector
{
    T * ptr;
    size_t count;

    typedef T value_type;

    FixedVector():ptr(0),count(0) {}
    ~FixedVector()
    {
        DeleteArr(ptr); // Error message appears here
        count=0;
    }
// ...
}
于 2012-09-26T10:40:31.623 に答える