2

次のコードを見てください。

template <typename K,typename T>
Pointer<typename Collection<T>::Iterator> BinaryTree<K,T>::GetBeginning() const
{
    return new BinaryTreeIterator(this,BinaryTreeIterator::Position::atBeginning);
}

VSTS 2008 を使用してコンパイルしようとすると、次のようになります。

error C2244: 'BinaryTree<K,T>::GetBeginning' : unable to match function definition to an existing declaration
see declaration of 'BinaryTree<K,T>::GetBeginning'
2>        definition
2>        'Pointer<Collection<T>::Iterator> BinaryTree<K,T>::GetBeginning(void) const'
2>        existing declarations
2>        'Pointer<Collection<T>::Iterator> BinaryTree<K,T>::GetBeginning(void) const'

宣言:

Pointer<Iterator> GetBeginning() const;

クラス内です。BinaryTree は Collection から間接的に継承し、BinaryTreeIterator は Iterator から間接的に継承します。どちらもそれぞれのコンテナーのネストされたクラスです。

エラー レポートでも、定義と宣言の両方が同一であることが簡単にわかります。ここで本当に何か問題がありますか?

Microsoft が修正プログラムをリリースしたことを発見しました:「特定のテンプレート コードがコンパイルされず、Visual Studio 2005 Service Pack 1 をインストールした後にエラー C2244 が発生する」。ただし、VSTS 2008 への参照は見つかりませんでした。

最初に、誰かがコードの実際のエラーを一目で見つけられるかどうかを確認したかったのですが、それがVSのせいである場合、上記の修正プログラムが解決策であり、2008年にも関連しているかどうかを知っている人はいますか.

4

3 に答える 3

2

興味のある人のために、私は問題を再現する最小限のサンプルを書いてみました:

template <typename T>
struct Pointer {};

template <typename T>
struct Collection {
    struct Iterator {};
};

template <typename K,typename T>
struct BinaryTree : Collection<T>{
    Pointer<typename Collection<T>::Iterator> GetBeginning() const;

    struct BinaryTreeIterator : Collection<T>::Iterator {
        template <typename X>
        BinaryTreeIterator(BinaryTreeIterator*, X) {}
        struct Position {
            static int atBeginning() { return 0; }
        };
    };
};

template <typename K,typename T>
Pointer<typename Collection<T>::Iterator> BinaryTree<K,T>::GetBeginning() const
{
    return Pointer<typename Collection<T>::Iterator>();
}

int main(){
    BinaryTree<int, float> bt;
    bt.GetBeginning();
}

はい、私もエラーが発生します。私たちがあなたのコードで見たものに明らかなエラーは見られませんが、この例でも、ほとんどの正気のC ++プログラマーが1年間に使用するよりも多くのネストされたクラスと継承を使用しているため、はっきりとは言えませんコードが正しいか正しくないか。

さらに、これをつなぎ合わせるにはかなりの推測が必要でした。(atBeginningは何であると想定されていますか?実際のクラスインターフェイスは何ですか?)

しかし、他のすべてからすべてを継承していなければ、よりうまく機能する(そしてより読みやすく、デバッグしやすい)と思います。

アップデート GCCとComeauのオンラインコンパイラで上記をコンパイルしてみましたが、どちらも受け入れました。したがって、コンパイラのバグである可能性があります。

于 2009-09-28T00:47:25.500 に答える
1

おそらくあなたが考えた明らかな解決策は、後で再定義するのではなく、クラス定義内で関数を定義することです。

また、次のようにイテレータ型を typedef に入れます。

template <typename T>
struct Pointer {};

template <typename T>
struct Collection {
    struct Iterator {};
};

template <typename K,typename T>
struct BinaryTree : Collection<T>{
    typedef typename Collection<T>::Iterator Iter;
    Pointer<Iter> GetBeginning() const;

    struct BinaryTreeIterator : Collection<T>::Iterator {
    };
};

template <typename K,typename T>
Pointer<typename BinaryTree<K,T>::Iter> BinaryTree<K,T>::GetBeginning() const
{
    return new BinaryTreeIterator(this,BinaryTreeIterator::Position::atBeginning);
}

int main(){
    BinaryTree<int, float> bt;
    bt.GetBeginning();
}

それを修正するようです。原因不明、バグかも…

于 2009-09-28T01:01:54.507 に答える
0

It will compile if you change it to this:

template <typename K,typename T>
struct BinaryTree : Collection<T> {
    Pointer<typename BinaryTree<K,T>::Iterator> GetBeginning() const;

};

template <typename K,typename T>
Pointer<typename BinaryTree<K,T>::Iterator> BinaryTree<K,T>::GetBeginning() const
{
    return Pointer<BinaryTree<K,T>::Iterator>();
}

In general, the original code isn't quite right because it implies that GetBeginning() can return any collection, while (I'm assuming) it can only return binary tree collections.

EDIT:

After some digging, it seems that VC++ doesn't handle well injected class names. That is, the original code will compile if you remove from Collection::Iterator in the method declaration:

template <typename K, typename T>
struct BinaryTree : Collection<T> {
    Pointer<typename Collection::Iterator> GetBeginning() const;

};

template <typename K, typename T>
Pointer<typename Collection<T>::Iterator> BinaryTree<K,T>::GetBeginning() const
{
    return Pointer<Collection<T>::Iterator>();
}
于 2009-09-28T15:20:28.783 に答える