6

The following gives a compiler error:

  #include <string>

  const std::string& get_name();

  int main(){
    auto&& name1 = get_name();//should bind to whatever
    const auto& name2 = get_name();//also ok
    const auto&& name3 = get_name();//<-not ok, why ?
    return 0;
  }

Link to godbolt: https://godbolt.org/z/l6IQQ7

If I use const auto& it compiles - but that will not bind to value. auto&& will be bind to anything so that naturally works as well. However, what is the logic behind const auto&& not binding in this case ? I know auto&& will preserve the constness - but is there a way to be const explicit and at the same time be reference/value agnostic ?

Motivation:

For 'normal programming work' inside functions etc. it would be great to be able to say something like: "I do not care if it's a value or reference - but I do not change it for the rest of the function".

This should be possible given current language.

Related question: Why adding `const` makes the universal reference as rvalue

darune
  • 10,480
  • 2
  • 24
  • 62
  • 1
    A [duplicate](https://stackoverflow.com/questions/38814939/why-adding-const-makes-the-universal-reference-as-rvalue)? This question asks about template type deduction, but as the rules are identical to `auto` in this case, I think we can close it? – lubgr Oct 09 '19 at 07:51
  • @lubgr I did see that actually- It's not framed the same - also Im asking for a 'solution' – darune Oct 09 '19 at 07:52
  • 1
    a 'solution' is to just use const auto&. it binds to everything. and you wont get any advantage if you somehow get a const rvalue ref – phön Oct 09 '19 at 08:05
  • @phön ty, thats a bit surprising though, please write an answer with explaination. – darune Oct 09 '19 at 08:09
  • @phön I mean, intuitively you would think a returned value into 'const reference' like that would be destructed after that statement. – darune Oct 09 '19 at 08:25
  • @darune yes. but thats lifetime extention. you get it for rvalue refs and const lvalue refs. https://en.cppreference.com/w/cpp/language/reference_initialization#Lifetime_of_a_temporary – phön Oct 09 '19 at 08:44

1 Answers1

5

For 'normal programming work' inside functions etc. it would be great to be able to say something like: "I do not care if it's a value or reference - but I do not change it for the rest of the function".

You already have the solution at hand for your motivation: use const auto&. const auto& will bind to:

  • const lvalue refs
  • lvalue refs
  • const rvalue refs
  • rvalue refs
  • Additionally, it will extend the lifetime of returned values

So you got everything you need. Yes, it is different from a const rvalue ref, but that wont matter if you just use it, since you wont be able to move from it anyway, since it is const.

Last note: auto&& will always be a reference. its a forwarding reference with deduction, but your final variable will ALWAYS be a reference (rvalue ref or lvalue ref, but never a "value"). Maybe that was/is a misconception?

Jarod42
  • 203,559
  • 14
  • 181
  • 302
phön
  • 1,215
  • 8
  • 20