2011-09-08 15 views
6

¿Hay algún lugar donde pueda confirmar esto? No estoy seguro si es el problema de GCC o mi código. Por ejemplo, el siguiente código no compila:GCC 4.4/4.5 unique_ptr no funciona para unordered_set/unordered_map

#include <unordered_set> 
#include <memory> 
using namespace std; 

int main() { 
    unordered_set<unique_ptr<int> > s; 
    unique_ptr<int> p(new int(0)); 
    s.insert(move(p)); 
    return 0; 
} 

El mensaje de error es demasiado grande y no quiero ponerlo aquí. La versión de GCC es 4.5.3, el indicador de compilación es -std = gnu ++ 0x. También probado en 4.4.5.

+0

Esto es probablemente porque 'std :: hash' no está especializado para' std :: unique_ptr'. – Mankarse

+1

@Mankarse Existe una especialización para esto, pero confusamente aparece en 20.7.2.6 Compatibilidad con el hash Smart Pointer [util.smartptr.hash] (n3290) justo después de las especificaciones para 'std :: shared_ptr', algo lejos de' std :: unique_ptr'. –

+0

N.B. debería decir 'std :: move' not' move', no quiere que ADL encuentre una función diferente. –

Respuesta

4

Tu código es correcto. Este es un problema conocido en GCC 4.5. Se ha corregido en 4.6. Ver http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44436. También afecta los contenedores ordenados (std :: map, std :: set etc). Probablemente, la solución más fácil (con una leve penalización de rendimiento) sería usar std :: shared_ptr en lugar de std :: unique_ptr.

8

GCC 4.6.1 acepta su código como está y no veo nada de malo en él (es decir, el tipo de valor de un contenedor asociativo debe ser EmplaceInsertable y std::unique_ptr no lo impide). Presumiblemente esto es una deficiencia en GCC 4.5.

3

Puedo confirmar que este es un problema con GCC 4.4.5. El intento de insertar una unique_ptr en un std :: set resultados en un mensaje de error del compilador de largo, que alude al hecho de que alguna función en el STL intentó copiar el unique_ptr:

error: deleted function [unique_ptr's copy ctor]... used here [g++-v4/bits/stl_tree.h:136].

La función STL en cuestión es parte de la estructura de árbol interno de varias clases de STL, incluido std :: set. También está dentro de un "__GXX_EXPERIMENTAL_CXX0X__" ifdef, lo que presumiblemente significa que GCC 4.4 no admite oficialmente lo que estamos tratando de hacer.

Si no desea actualizar a GCC 4.6, siempre puede ajustar un std :: vector y buscar y eliminar estratégicamente duplicados en ciertos puntos de su código.