Search code examples
c++rvalue-reference

Pass rvalue by reference


I am struggling to turn this piece of code into a one-liner:

std::string filename = "cats";
std::shared_ptr<bmd2::Bmd2Dataset> ptr (new bmd2::Bmd2Dataset(filename, bmd2::File::FM_WRITE));
bmd2::bmd2Session::getInstance().addDataset(ptr);

The above works great -- but can I call addDataset without creating the lvalues (lines 1 + 2)?

Here is the declaration of addDataset():

int addDataset(std::shared_ptr<bmd2::Bmd2Dataset> &) throw (bmd2Exception);

Solution

  • bmd2::bmd2Session::getInstance().addDataset(
       std::make_shared<bmd2::Bmd2Dataset>("cats", bmd2::File::FM_WRITE)
    );
    

    One statementer. :)

    Interesting. For learning purposes, can you tell me if you can accomplish this without the make_shared() function call?

    You can, using C++11's brace initialization syntax. Assuming addDataset isn't a template and has std::shared_ptr<bmd2::Bmd2Dataset> as its parameter,

    bmd2::bmd2Session::getInstance().addDataset(
       { new bmd2::Bmd2Dataset("cats", bmd2::File::FM_WRITE) }
    );
    

    UPDATE: Oops. So addDataset() actually accepts an l-value reference why didn't you say so immediately?. addDataset()'s parameter can't bind to r-value parameters, which in the two above examples are. To solve this, you can either:

    • Make addDataset()'s parameter a const reference

      int addDataset(const std::shared_ptr<bmd2::Bmd2Dataset> &) throw (bmd2Exception);
      //             ^^^^^
      

      Do this if you don't need to modify the passed shared_ptr argument (i.e. modifying it so it points to another object).

    • Use your older method, though passing directly "cat" into the the new expression. UPDATE: Use std::make_shared!

      auto ptr = std::make_shared<bmd2::Bmd2Dataset>("cats", bmd2::File::FM_WRITE);
      bmd2::bmd2Session::getInstance().addDataset(ptr);
      // ptr might now point to some other object
      

      Do this if you want the passed argument's (ptr) value to be changed (i.e. after the call it might now point to a new object).