2012-10-03 14 views
10

Intenté introducir algo de const corrección (paradigmas realmente funcionales) a algún código nuevo y encontré que no puedo pasar un std::shared_ptr<A> a una función que espera un std::shared_ptr<A const>. Tenga en cuenta que no quiero lanzar distancia constness sino presentarlo, que es legal con punteros sin formato.¿Por qué no shared_ptr <A> convierte implícitamente a shared_ptr <A const>?

¿Hay alguna forma de evitar esto? No encontré una función de miembro para hacer esto.


El error precisa pronunciada por g ++ 4.6.1 es:

error: no matching function for call to ‘foo(std::shared_ptr<A>)’ 
note: candidate is: 
note: template<class T> std::shared_ptr<_Tp> foo(std::shared_ptr<const _Tp>) 

Respuesta

9

El problema en su caso no es con las posibles conversiones desde/a diferente std::shared_ptr, pero está más relacionado con la forma en la inferencia de tipos funciona para funciones de plantilla.

Cuando el compilador intenta hacer coincidir una llamada de función con una plantilla, solo aceptará coincidencias exactas, es decir, no habrá conversiones de tipo. En este caso, su función toma un std::shared_ptr<const T>, y la persona que llama tiene un std::shared_ptr<U> donde U no es const. Como la coincidencia no es exacta, descartará la plantilla y elegirá el siguiente candidato de sobrecarga.

Las soluciones simples son: evitar la inferencia de tipos en conjunto y proporciona el argumento de plantilla:

std::shared_ptr<A> p; 
foo<A>(p);    // will use the templated shared_ptr conversion 

o realizar la conversión a sí mismo:

foo(std::shared_ptr<const A>(p)); 
+0

'std :: static_pointer_cast (p)' es otra forma de hacer una conversión explícitamente –

+0

@Luc: ¿Por qué no 'std :: const_pointer_cast (p)'? – Xeo

+1

@ Xeo Porque no estamos eliminando cv-qualifiers. –

Cuestiones relacionadas