模板类的内部类不会在XCode 4.5.2上编译

Inner class of template class will not compile on XCode 4.5.2

本文关键字:XCode 编译 内部类      更新时间:2023-10-16

在XCode 4.5.2中,下面定义的类Proxy不编译。如果需要,我可以提供有关特定编译器的更多详细信息,尽管它应该是默认的,因为我在XCode配置中没有更改任何内容。它在VStudioExpress中编译。

#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>>'

(缓存的模板参数为std::basic_string<char>(

我理解正在发生的事情——在完全定义Proxy之前,我正在引用它。但是为什么iterator需要Proxy的定义来编译呢?

数据结构的原因有两个:1(回收对象而不是销毁它们,2(通过将缓存对象中的迭代器保持在列表中的位置来加快回收。如果有人对如何实现这些有更好的想法(假设这个错误无法修复(,我很想听听。

您的代码具有未定义的行为,因为您正在用不完整的类型实例化std::list(Proxy尚未在其定义中定义(。[res.on.functions]/2:

效果尚未确定。。。如果在实例化模板组件时使用不完整类型作为模板参数,除非该组件特别允许。

尝试使用list的实现,该实现适用于不完整的类型,例如boost::container::list。