Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

const forwarding reference gives error C2440: 'initializing': cannot convert from 'const std::string' to 'const std::string &&'

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

like image 373
darune Avatar asked Oct 09 '19 07:10

darune


1 Answers

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?

like image 107
phön Avatar answered Nov 01 '22 18:11

phön