c++constantsc++17type-traits

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


C++11 has given us std::add_const; with C++17, we have a new structure - std::as_const(). The former just tacks a const before the type you provide it with. The second one is a proper (template of a) function, not type trait, which seems to do the same - except for when the type is an rvalue-reference, in which case it cannot be used.

I don't quite understand the motivation for providing std::as_const(). Why do we need it in addition to std::add_const?


Solution

  • "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: