2010-08-04 14 views
11

Para agregar const a un objeto no const, ¿cuál es el método preferido? const_cast<T> o static_cast<T>. En una pregunta reciente, alguien mencionó que prefieren usar static_cast, pero yo hubiera pensado que const_cast dejaría más clara la intención del código. Entonces, ¿cuál es el argumento para usar static_cast para hacer una constante const?const_cast vs static_cast

Respuesta

14

No utilizar ninguno de los dos. Inicializar una referencia const que se refiere al objeto:

T x; 
const T& xref(x); 

x.f();  // calls non-const overload 
xref.f(); // calls const overload 

O bien, utilizar una plantilla de implicit_cast función, como the one provided in Boost:

T x; 

x.f();       // calls non-const overload 
implicit_cast<const T&>(x).f(); // calls const overload 

Dada la posibilidad de elegir entre static_cast y const_cast, static_cast es definitivamente preferible: const_cast debe solo se debe usar para descartar constness porque es el único molde que puede hacerlo, y la eliminación de la constness es intrínsecamente peligrosa. La modificación de un objeto a través de un puntero o una referencia obtenida mediante la eliminación de la constness puede dar como resultado un comportamiento indefinido.

+0

mayoría de los yesos pueden ser "peligroso". – curiousguy

+0

Scott Meyers da un ejemplo de usar un 'static_cast' para' const' seguido de un 'const_cast' para hacer que la versión non-'const' de' operator [] 'llame a la versión' const'. ¿Se puede lograr lo mismo usando una referencia constante? –

+0

Parece que * puedes * reemplazar el 'static_cast' al crear una nueva referencia de const, pero por supuesto debes usar' const_cast' para devolver una referencia que no sea const. Sin embargo, no estoy seguro de si esto es un comportamiento específico del compilador o plataforma, o si está implícito en alguno de los requisitos del estándar. –

2

diría static_cast es preferible, ya que sólo se permitirá lanzar a partir de la no constconst (que es seguro), y no en la otra dirección (que no es necesariamente seguro).

+0

Esto parece coincidir con la opinión de Scott Meyers; vea _Efectivo C++ _, artículo 3, en el ejemplo "Evitando duplicación ...". –

2

Este es un buen caso de uso para una plantilla de función implicit_cast.

1

Se puede escribir su propio reparto:

template<class T> 
const T & MakeConst(const T & inValue) 
{ 
    return inValue; 
} 
Cuestiones relacionadas