75

I know that you can use const_cast to cast a const to a non-const.

But what should you use if you want to cast non-const to const?

Motti
  • 110,860
  • 49
  • 189
  • 262
kamikaze_pilot
  • 14,304
  • 35
  • 111
  • 171

6 Answers6

62

const_cast can be used in order remove or add constness to an object. This can be useful when you want to call a specific overload.

Contrived example:

class foo {
    int i;
public:
    foo(int i) : i(i) { }

    int bar() const {
        return i;    
    }

    int bar() { // not const
        i++;
        return const_cast<const foo*>(this)->bar(); 
    }
};
Motti
  • 110,860
  • 49
  • 189
  • 262
  • 2
    Your method doesn't work in all cases ... `const_cast` needs a specific constructor for user class types. – Robin Rodricks Mar 23 '13 at 18:44
  • 4
    @Geotarget you are incorrect, no new object is created hence it doesn't matter which constructors are available. – Motti Mar 23 '13 at 19:43
  • 8
    You don't need `const_cast` to add the `const` qualifier -- doing so is 10+ extra characters of visual noise and so this practice is IMO a Bad Idea™. Just use `const foo* = obj;`. `const_cast` is most often (ab)used to [take `const` away](http://stackoverflow.com/questions/3803521/question-about-const-cast-in-c). – bobobobo Aug 21 '13 at 11:52
  • 3
    As a note regarding the people saying `const_cast` is bad for this: using `const_cast` in this way is helpful in a constructor's member initialization, where you can't make a local variable to add const. Additionally, I'd argue that the "visual noise" helps to make it obvious that something unusual is happening regarding const-ness. However, it's probably best to add a comment to clarify that you're _adding_ const, to make sure people do not instinctively lash out at the evil `const_cast`. – Aberrant Sep 25 '15 at 11:45
  • 2
    just to add: as pointed out adding constness is done implicitly and therefor one can also use a `static_cast(var)`. I personally almost never use const_cast as it mostly makes up for software architectural flaws in your code (when used to cast away constness). So when adding constness i use either the local variable approach or a static_cast to signal there is nothing fishy going on – Florian Tischler Apr 21 '16 at 19:56
50

STL since C++17 now provides std::as_const for exactly this case.

See: http://en.cppreference.com/w/cpp/utility/as_const

Use:

CallFunc( as_const(variable) );

Instead of:

CallFunc( const_cast<const decltype(variable)>(variable) );
Scott Langham
  • 58,735
  • 39
  • 131
  • 204
31

You don't need const_cast to add constness:

class C;
C c;
C const& const_c = c;

Please read through this question and answer for details.

Community
  • 1
  • 1
Ozair Kafray
  • 13,351
  • 8
  • 59
  • 84
7

You can use a const_cast if you want to, but it's not really needed -- non-const can be converted to const implicitly.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • 9
    To whomever did the downvote: since you're apparently not going to comment, or try to point out why you think this is wrong or unhelpful, could you at least do one more unwarranted downvote, so my rep score will be a multiple of 10 again? – Jerry Coffin May 02 '11 at 07:00
  • 9
    Implicit conversions from non-`const` to `const` is unreliable. Sometimes it needs to be explicit. For example, a method would distinguish between a `const` and non-`const` version of a parameter in order to return a `vector` of `reference_wrapper` of either `const`ness. Consider for instance this declaration: `template vector::value, const typename Image::celltype, typename Image::celltype>::type>> get_subimage(int, int, Image&);`. – kccqzy Oct 23 '13 at 06:19
3

const_cast can be used to add constness behavior too.

From cplusplus.com:

This type of casting manipulates the constness of an object, either to be set or to be removed.

Omar Hussein
  • 39
  • 1
  • 9
beduin
  • 7,943
  • 3
  • 27
  • 24
2

You have an implicit conversion if you pass an non const argument to a function which has a const parameter

Guillaume Paris
  • 10,303
  • 14
  • 70
  • 145