1

XCode 4.5.2 では、Proxy以下に定義されているクラスはコンパイルされません。XCode 構成で何も変更していないため、デフォルトにする必要がありますが、必要に応じて特定のコンパイラについて詳しく説明できます。VStudio Express でコンパイルされます。

#include <list>
#include <boost/thread/tss.hpp>

template <typename T>
class Cache
{
public:
    class Proxy : public T
    {
        friend class Cache;

    private:
        std::list<Proxy> & m_refList;
        typename std::list<Proxy>::iterator m_clsPosition;

        Proxy(std::list<Proxy> & refList) : m_refList(refList) {}
    };

private:
    std::list<Proxy> m_clsList;
    typename std::list<Proxy>::iterator m_clsCurrent;

    static void Release(Proxy * ptrProxy)
    {
        ptrProxy->m_refList.splice(ptrProxy->m_refList.m_clsCurrent,
                                   ptrProxy->m_refList,
                                   ptrProxy->m_clsPosition);
        if ( ptrProxy->m_refList.m_clsCurrent == ptrProxy->m_refList.end() )
            --(ptrProxy->m_refList.m_clsCurrent);
    }

public:
    Cache() {m_clsCurrent = m_clsList.end();}
    ~Cache()
    {
        if ( m_clsList.size() && m_clsCurrent != m_clsList.begin() )
        {
            // ERROR - Cache not empty
        }
    }

    typedef boost::shared_ptr<Proxy> Ptr;

    static Ptr Get()
    {
        static boost::thread_specific_ptr<Cache> clsCache;
        if ( clsCache.get() == NULL )
            clsCache.reset(new Cache());

        Proxy * ptrProxy;
        if ( clsCache->m_clsCurrent == clsCache->m_clsList.end() )
        {
            clsCache->m_clsList.push_front(Proxy(clsCache->m_clsList));
            ptrProxy = &(clsCache->m_clsList.front());
            ptrProxy->m_clsPosition = clsCache->m_clsList.begin();
        }
        else
        {
            ptrProxy = &(*(clsCache->m_clsCurrent));
            ptrProxy->m_clsPosition = clsCache->m_clsCurrent++;
        }
        return Ptr(ptrProxy, Release);
    }
};

コンパイルエラーは次の行にありますtypename std::list<Proxy>::iterator m_clsPosition

No type named 'iterator' in 'std::__1::list<ASW::Cache<std::__1::basic_string<char>>::Proxy, std::__1::allocator<ASW::Cache<std::__1::basic_string<char>>::Proxy>>'

(Cache へのテンプレート パラメータはstd::basic_string<char>)

何が起こっているのか理解しています -Proxy完全に定義される前に参照しています。しかし、なぜコンパイルするためiteratorに の定義が必要なのでしょうか?Proxy

データ構造の理由は 2 つあります。1) オブジェクトを破棄するのではなく再利用するため、2) キャッシュされたオブジェクト内の反復子をリスト内のその位置に保持することにより、再利用を促進するためです。誰かがこれらを実装する方法についてより良いアイデアを持っている場合 (このエラーを修正できない場合)、私はそれを聞くことに興味があります.

4

1 に答える 1

2

std::list不完全な型 (Proxyはその定義内でまだ定義されていません) でインスタンス化しているため、コードには未定義の動作があります。[res.on.functions]/2:

... 影響は未定義です ... テンプレート コンポーネントをインスタンス化するときに、そのコンポーネントで特に許可されていない限り、不完全な型がテンプレート引数として使用された場合。

boost::container::listなど、不完全なタイプで機能listするの実装を使用してみてください。

于 2013-02-27T04:58:56.170 に答える