why auto i = same_const_variable could not deduce “const”?

前端 未结 2 1896
北荒
北荒 2021-01-06 10:52
const int ci = 10;
auto i = ci;  // i will be \"int\" instead of \"const int\"
i = 20;

I am wondering why auto is designed for this kind of behavio

相关标签:
2条回答
  • 2021-01-06 11:12

    auto by itself means that you want a new, locally-owned variable with a copy of the given value. const-ness is not part of value. An int is an int whether it's specified using a literal, a named constant, an expression, or a non-const variable.

    auto i = 3,
         j = i,
         k = ci,
         m = 3 + 4; // All these variables are type int.
    

    To get a constant of deduced type, you can still use auto const. This expresses within the declaration how the variable may be used.

    const auto i = 3;
    

    Since C++14, there is also the decltype(auto) specifier which applies decltype to the initializer, to make a carbon copy of the given variable. Perhaps that's really what you expected:

    decltype(auto) i = ci; // i receives type const int.
    

    Live demo.

    decltype(auto) is a bit tricky, though, and it has few use cases aside from its original purpose relating to deciding the return type of function call wrappers. Unless there's a good reason, choose const auto or const int instead.

    Another alternative is to use a forwarding reference, spelled auto &&. This refers to the variable or value that initializes it, whatever that may be.

    auto && i = ci; // i receives type const int & and aliases ci.
    

    This is less expressive and specific, but reliably declares i as an alias to ci. The other thing you tried was auto &, which is similar but only allows forming a reference to a preexisting variable.

    auto & i = ci; // i receives type const int & and aliases ci.
    

    A reference to a const int variable must be of type const int &, because otherwise it would permit illegal modification.

    0 讨论(0)
  • 2021-01-06 11:29

    auto mostly follows the same type deduction rules as template argument deduction. The only difference is that auto will deduce std::initializer_list from a braced-init-list in some cases, while template argument deduction doesn't do this.

    From N3337, §7.1.6.4 [dcl.spec.auto]

    6   ... The type deduced for the variable d is then the deduced A determined using the rules of template argument deduction from a function call (14.8.2.1), ...

    The behavior you're observing is the same as what template argument deduction would do when deducing types from a function call

    §14.8.2.1 [temp.deduct.call]

    2   If P is not a reference type:
        — ...
        — If A is a cv-qualified type, the top level cv-qualifiers of A’s type are ignored for type deduction.

    Thus, in

    auto i = ci;
    

    the top level const qualifier is ignored and i is deduced as int.

    When you write

    auto& i = ci;
    

    then i is no longer not a reference type and the above rule doesn't apply, so the const qualifier is retained.

    0 讨论(0)
提交回复
热议问题