What do we need std::as_const() for?

“Need” is a strong word… std::as_const exists because it’s useful, not strictly necessary. Since it’s a function rather than a trait, we can use it to “add const” to actual values rather than to types.

More specifically: Suppose I have some variable my_value and I want to treat it as a const, but not copy it. Before C++17 I would need to write:

static_cast<const MyType&>(my_value)

and if I don’t want to specify the type explicitly, it would be:

static_cast
   <std::add_const_t<std::remove_reference_t<decltype(my_value)>> &>
   (my_value)

or if you want to get down and dirty, and use C-style casting:

(const decltype(my_value) &) (&my_value)

all of which are annoying and verbose.

Instead of these, with C++17 now write std::as_const(my_value) and that’s all there is to it.

Notes:

  • This function is disabled for rvalue references even though it works just fine for them. The reason is to help you avoid inadvertantly keeping a reference to a temporary past its destruction. As @NicolBolas explains, if you write something like:

    for(auto &x : std::as_const(returns_container())) { /* do stuff with x */ }
    

    then the returned container’s lifetime ends before the first iteration of the loop. Very easy to miss!

  • For additional (?) information, consult the official proposition of this utility function: P007R1, by Adam David Alan Martin and Alisdair Meredith.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)