-1

Here is a snippet of code which causes a C2664 error:

cannot convert argument 1 from 'std::unique_ptr<Component,std::default_delete<_Ty>>' to 'ComPtr &'

So why must a non-const reference be initialized with an lvalue? How to avoid this except by declaring a new variable?

#include <memory>
#include <list>

class Component {
};

using ComPtr = unique_ptr<Component>;
using ComList = list<ComPtr>;
ComList coms;

void addComponent(ComPtr&c) {
    coms.push_back(c);
}

int main() {
    addComponent(make_unique<Component>()); //Error here.
    return 0;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Y.Lex
  • 241
  • 1
  • 7
  • @PaulRooney "It wouldnt be a great idea for the compiler to allow us to make changes to a temporary would it?" That's exactly what r-value references let you do. – xaxxon Aug 14 '18 at 04:10
  • 4
    Possible duplicate of [How come a non-const reference cannot bind to a temporary object?](https://stackoverflow.com/questions/1565600/how-come-a-non-const-reference-cannot-bind-to-a-temporary-object) –  Aug 14 '18 at 04:11

1 Answers1

4

The way to write this so you don't have to do what you're fighting with is: https://godbolt.org/g/vceL4q

#include <memory>
#include <list>
using namespace std;

class Component {
};

using ComPtr = unique_ptr<Component>;
using ComList = list<ComPtr>;
ComList coms;

void addComponent(ComPtr c) { // <== change here
    coms.push_back(std::move(c)); // and here
}

int main() {
    addComponent(make_unique<Component>());
    return 0;
}

The c in addComponent will be created via a move constructor because the result of make_unique is an rvalue.

It's preferred to pass in large (move friendly) data structures by value this way.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
xaxxon
  • 19,189
  • 5
  • 50
  • 80