2012-02-03 9 views
5

He creado un mapa no copiable que no puedo compilar con clang. Como clang se supone que cumple con los estándares, me preguntaba si mi código era legal. MSVS 2010 y GCC 4.7 compilan este código sin advertencias ni errores.¿Este mapa no copiable es legal C++ 11? GCC 4.7 y MSVS 2010 lo permiten. Clang 3.1 no

Se adjunta el código completo: la línea problemática es la última línea de main.

= delete necesidades eliminación de MSVS 2010

#include <utility> 
#include <iostream> 
#include <map> 

template<typename Key_t, typename Value_t, typename Compare_t = std::less<Key_t> > 
class non_copyable_map : public std::map<Key_t,Value_t,Compare_t> 
{ 
    typedef std::map<Key_t,Value_t,Compare_t> BaseType; 

    public: 
    non_copyable_map() { } 

    non_copyable_map(non_copyable_map&& t) : BaseType(std::move(t)) {} 

    non_copyable_map& operator = (non_copyable_map&& t) 
    { 
     if (this != &t) 
     { 
     std::swap<BaseType>(*this,t); 
     } 
     return *this; 
    } 

    private: 
    non_copyable_map(const non_copyable_map&) = delete; 
    non_copyable_map& operator = (const non_copyable_map&) = delete; 
}; 

int main(int argc, char* argv[]) 
{ 
    non_copyable_map<int, non_copyable_map<int, int> > nestedMap; 
    non_copyable_map<int,int> inner; 
    inner[3]=4; 
    nestedMap[2] = std::move(inner); // THIS LINE CAUSES CLANG PROBLEMS 
} 

mensaje de error cuando se utiliza clang++-mp-3.1 -std=c++0x -stdlib=libc++ MapOfMaps.cpp es:

In file included from MapOfMaps.cpp:2: 
In file included from /usr/include/c++/v1/iostream:40: 
In file included from /usr/include/c++/v1/istream:156: 
In file included from /usr/include/c++/v1/ostream:134: 
In file included from /usr/include/c++/v1/bitset:118: 
/usr/include/c++/v1/__bit_reference:26:26: error: no type named '__storage_type' in 
     'std::__1::map<int, int, std::__1::less<int>, std::__1::allocator<std::__1::pair<const 
     int, int> > >' 
    typedef typename _C::__storage_type __storage_type; 
      ~~~~~~~~~~~~~^~~~~~~~~~~~~~ 
MapOfMaps.cpp:21:25: note: in instantiation of template class 
     'std::__1::__bit_reference<std::__1::map<int, int, std::__1::less<int>, 
     std::__1::allocator<std::__1::pair<const int, int> > > >' requested here 
           std::swap<BaseType>(*this,t); 
                ^
MapOfMaps.cpp:36:15: note: in instantiation of member function 'non_copyable_map<int, int, 
     std::__1::less<int> >::operator=' requested here 
     nestedMap[2] = std::move(inner); 
        ^
In file included from MapOfMaps.cpp:2: 
In file included from /usr/include/c++/v1/iostream:40: 
In file included from /usr/include/c++/v1/istream:156: 
In file included from /usr/include/c++/v1/ostream:134: 
In file included from /usr/include/c++/v1/bitset:118: 
/usr/include/c++/v1/__bit_reference:27:26: error: no type named '__storage_pointer' in 
     'std::__1::map<int, int, std::__1::less<int>, std::__1::allocator<std::__1::pair<const 
     int, int> > >' 
    typedef typename _C::__storage_pointer __storage_pointer; 
      ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~ 
/usr/include/c++/v1/__bit_reference:33:25: error: no type named '__self' in 
     'std::__1::map<int, int, std::__1::less<int>, std::__1::allocator<std::__1::pair<const 
     int, int> > >' 
    friend typename _C::__self; 
      ~~~~~~~~~~~~~^~~~~~ 
In file included from MapOfMaps.cpp:3: 
In file included from /usr/include/c++/v1/map:338: 
/usr/include/c++/v1/__tree:1291:14: error: overload resolution selected deleted operator '=' 
    __pair3_ = _STD::move(__t.__pair3_); 
    ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~ 
/usr/include/c++/v1/__tree:1308:9: note: in instantiation of member function 
     'std::__1::__tree<std::__1::pair<int, int>, std::__1::__map_value_compare<int, int, 
     std::__1::less<int>, true>, std::__1::allocator<std::__1::pair<int, int> > 
     >::__move_assign' requested here 
     __move_assign(__t, true_type()); 
     ^
/usr/include/c++/v1/__tree:1353:5: note: in instantiation of member function 
     'std::__1::__tree<std::__1::pair<int, int>, std::__1::__map_value_compare<int, int, 
     std::__1::less<int>, true>, std::__1::allocator<std::__1::pair<int, int> > 
     >::__move_assign' requested here 
    __move_assign(__t, integral_constant<bool, 
    ^
/usr/include/c++/v1/map:736:21: note: in instantiation of member function 
     'std::__1::__tree<std::__1::pair<int, int>, std::__1::__map_value_compare<int, int, 
     std::__1::less<int>, true>, std::__1::allocator<std::__1::pair<int, int> > >::operator=' 
     requested here 
      __tree_ = _STD::move(__m.__tree_); 
        ^
/usr/include/c++/v1/type_traits:2342:9: note: in instantiation of member function 
     'std::__1::map<int, int, std::__1::less<int>, std::__1::allocator<std::__1::pair<const 
     int, int> > >::operator=' requested here 
    __x = _STD::move(__y); 
     ^
MapOfMaps.cpp:21:5: note: in instantiation of function template specialization 
     'std::__1::swap<std::__1::map<int, int, std::__1::less<int>, 
     std::__1::allocator<std::__1::pair<const int, int> > > >' requested here 
           std::swap<BaseType>(*this,t); 
           ^
MapOfMaps.cpp:36:15: note: in instantiation of member function 'non_copyable_map<int, int, 
     std::__1::less<int> >::operator=' requested here 
     nestedMap[2] = std::move(inner); 
        ^
/usr/include/c++/v1/memory:1918:7: note: candidate function (the implicit copy assignment 
     operator) has been explicitly deleted 
class __compressed_pair 
    ^
4 errors generated. 
+0

¿Qué mensaje de error específico está recibiendo? – templatetypedef

+0

He agregado errores al final de la publicación inicial – jbcoe

Respuesta

1

esto puede ser un error ++ sonido metálico o libc (lo más probable libC++). No estoy duplicando su síntoma con herramientas de punta de tronco. Los últimos encabezados de libC++ son here. Esto es un poco de un tiro en la oscuridad, pero intente esto:

swap(static_cast<BaseType&>(*this),static_cast<BaseType&>(t)); 

Parece que estás enredarse con este swap en <__bit_reference>:

template <class _Cp, class _Dp> 
_LIBCPP_INLINE_VISIBILITY inline 
void 
swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT 

que no tiene nada que ver con mapas. Simplemente sucede que está en el alcance.

+0

Eso solucionó el problema. Gracias. ¿Alguna idea de lo que causó el enredo con 'swap' en' <__ bit_reference> '? – jbcoe

+0

Hice un poco de espeleología (muy poco, unos minutos) y encontré esto: http://llvm.org/bugs/show_bug.cgi?id=10248 Parece muy similar a su caso, y allí estoy argumentando que su código no es conforme, o debería ser (creo que por llamarlo con un parámetro de plantilla explícita). Para decirte la verdad, han pasado 7 meses desde que escribí eso, y no puedo recordar los detalles esta noche (mi cerebro está ocupado en otra parte). Sin embargo, verifiqué una medida provisional para proteger el intercambio en __bit_reference en ese momento, y eso parece ser lo que protege el código de la punta del tronco. –

Cuestiones relacionadas