Visual Studio 2013 中的 select_on_container_copy_construction 内部错误

Posted

技术标签:

【中文标题】Visual Studio 2013 中的 select_on_container_copy_construction 内部错误【英文标题】:select_on_container_copy_construction internal error in visual studio 2013 【发布时间】:2014-04-13 13:49:16 【问题描述】:

我在 Visual Studio 2013 中遇到内部编译器错误。确切的错误是

c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(487): fatal error     C1001: An internal error has occurred in the compiler.
2>  (compiler file 'f:\dd\vctools\compiler\utc\src\p2\ehexcept.c', line 1483)
2>   To work around this problem, try simplifying or changing the program near the locations listed above.

这指向我在 std::allocator_traits 的实现中的这段代码:

static _Alloc select_on_container_copy_construction(
    const _Alloc& _Al)
       // get allocator to use
    return (_Alloc_select::_Fn(0, _Al));
    

据此,我认为问题与我为自定义分配器所做的实现有关。这个分配器是一个类模板,用于包装我在项目中使用且不符合标准的更简单的分配器(因此需要包装)。 包装如下:

template<class BaseAlloc_, class T_>
    class StdAllocator : public BaseAlloc_ 
    public:
        // Public types
        typedef T_              value_type;
        typedef T_*             pointer;
        typedef const T_*       const_pointer;
        typedef T_&             reference;
        typedef const T_&       const_reference;
        typedef std::size_t     size_type;
        typedef std::ptrdiff_t  difference_type;

    public:
        // Convert an allocator<T_> to allocator<U_>
        template<typename U_>
        struct rebind 
            typedef StdAllocator<BaseAlloc_,U_> other;
        ;

    public:
        inline explicit StdAllocator():BaseAlloc_() 
        inline explicit StdAllocator(BaseAlloc_ _b) :BaseAlloc_(_b) 
        inline ~StdAllocator() 
        inline explicit StdAllocator(StdAllocator const& _x) :BaseAlloc_(_x) 
        template<typename U>
        inline explicit StdAllocator(StdAllocator<BaseAlloc_,U> const&) :BaseAlloc_() 

        //    address
        inline pointer address(reference r)  return &r; 
        inline const_pointer address(const_reference r)  return &r; 

        //    memory allocation
        inline pointer allocate(size_type _cnt,
            typename std::allocator<void>::const_pointer = 0) 
            return BaseAlloc_::allocate<T_>(_cnt);
        
        inline void deallocate(pointer _p, size_type _cnt) 
            BaseAlloc_::deallocate(_p,_cnt);
        

        //    size
        inline size_type max_size() const 
            return std::numeric_limits<size_type>::max() / sizeof(T_);
        

        //    construction/destruction
        inline void construct(pointer p, const T_& t)  new(p)T_(t); 
        inline void destroy(pointer _p)  
            _p; // Work around for visual studio incorrect warning
            _p->~T_();
        

        inline bool operator==(StdAllocator const&)  return true; 
        inline bool operator!=(StdAllocator const& a)  return !operator==(a); 
    ;

鉴于 Visual Studio 没有提供更多信息,我不知道如何解决这个问题。

【问题讨论】:

ICE 始终是编译器中的错误。报告它,例如到connect.microsoft.com 不确定为什么复制和默认构造函数是显式的。另外,inline 在这里只是噪音。 不,它并不总是编译器中的错误。您已经编写了代码,通常是模板代码,它们非常复杂以至于编译器无法解决问题。分而治之。从可以编译的东西开始,并用不编译的代码替换部分,直到你发现你做错了什么。你会发现你试图做一些编译器从来没有打算做的事情。这不是我们所说的错误。 @Dan 我还没有看到与内存耗尽或违反实现限制等相关的错误消息。即使该错误消息根本没有帮助。 @technik 见Where and why do I have to put the “template” and “typename” keywords?。例如,BaseAlloc_::allocate&lt;T_()&gt;(_cnt); 会模棱两可;此外,template 关键字允许更早的语法检查。 // 允许使用 explicit 默认/复制 ctor;正如我之前所说,这可能是一个编译器错误。 【参考方案1】:

我读了这篇文章和链接的文章,半小时后才看到一条评论回答了这个问题:“令人惊讶的是,从 默认构造函数 中删除了 explicit 关键字和copy-constructor 是 Visual Studio 所需要的,现在代码编译成功。” 这对我有用。 我把它复制到一个答案不是为了窃取它而是为了暴露它。

【讨论】:

以上是关于Visual Studio 2013 中的 select_on_container_copy_construction 内部错误的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio 2013 中的默认模板项目崩溃

克服 Visual Studio 2013 中的 decltype 问题

Visual Studio 2013 中的“无法导入 ActiveX 控件”

Visual Studio 2013 中的 LoadTestException 错误

Visual Studio 2013 中的 Resharper 8.0

C++ 中的溢出数字 (Visual Studio 2013)