13

To add const to a non-const object, which is the prefered method? const_cast<T> or static_cast<T>. In a recent question, someone mentioned that they prefer to use static_cast, but I would have thought that const_cast would make the intention of the code more clear. So what is the argument for using static_cast to make a variable const?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Anthony
  • 12,177
  • 9
  • 69
  • 105

4 Answers4

18

Don't use either. Initialize a const reference that refers to the object:

T x;
const T& xref(x);

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

Or, use an implicit_cast function template, like the one provided in Boost:

T x;

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

Given the choice between static_cast and const_cast, static_cast is definitely preferable: const_cast should only be used to cast away constness because it is the only cast that can do so, and casting away constness is inherently dangerous. Modifying an object via a pointer or reference obtained by casting away constness may result in undefined behavior.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • Most casts can be "dangerous". – curiousguy Dec 20 '11 at 21:32
  • Scott Meyers gives an example of using a `static_cast` to `const` followed by a `const_cast` to cause the non-`const` version of `operator[]` to call the `const` version. Can the same be achieved using a const reference? – Kyle Strand Jul 31 '14 at 17:42
  • It looks like you *can* replace the `static_cast` by instantiating a new const reference, but of course you must still use `const_cast` to return a non-const reference. I'm not sure if this is compiler- or platform-specific behavior, though, or if it's implied by any of the requirements in the standard. – Kyle Strand Jul 31 '14 at 23:19
3

I'd say static_cast is preferable since it will only allow you to cast from non-const to const (which is safe), and not in the other direction (which is not necessarily safe).

bcat
  • 8,833
  • 3
  • 35
  • 41
  • This appears to match Scott Meyers' opinion; see _Effective C++_, Item 3, in the "Avoiding Duplication..." example. – Kyle Strand Jul 31 '14 at 17:24
2

This is a good use case for an implicit_cast function template.

Community
  • 1
  • 1
Ken Bloom
  • 57,498
  • 14
  • 111
  • 168
1

You could write your own cast:

template<class T>
const T & MakeConst(const T & inValue)
{
    return inValue;
}
StackedCrooked
  • 34,653
  • 44
  • 154
  • 278