0

I am working on a project for school and I am essentially creating a doubly linked list using a hybrid of unique_ptrs and raw ptrs.

One of the test cases is reversing the user-defined doubly linked list and return a temporary object. This is fine and I would assume that when the gets returned if I am instantiating another object from it... this would call the move constructor when provided one.

But after testing weirdly enough no constructor at ALL is being called to give you guys an understanding here is the code and ill break it down.

  HW08::DList<std::string> list = {"Carlos", "Bob", "Birian", "Hero", "Goat"};
  {
    HW08::DList<std::string> list2(list.reverse());
    list2.print();
  }
  list.print();
  DList reverse() const {
    Node<T>* node = tail_;
    DList<T> tList(this->size_);

    for (int i = 0; i < tList.size(); i++) {
      tList[i] = node->val_;
      node = node->prev_;
    }
    return tList;
  }
// Constructor with initializer list
DList(std::initializer_list<T> init) : size_(init.size());
// Only size provided constructor
DList(const int &size) : size_(size), tail_(nullptr);
// Copy constructor
DList(const DList &rhs) : size_(rhs.size_);
// Copy assignment
DList &operator=(const DList &rhs);
// Move constructor
DList(DList &&rhs) noexcept : size_(rhs.size_);
// Move assignment
DList &operator=(DList &&rhs);

This is the code essentially I did not provide implementations to the constructors HERE since all that is needed to know is that they are not being called, I am outputting in each of the constructors but none are getting called besides the first object using initializer_list.

init constructor
[ Goat, Hero, Birian, Bob, Carlos ]
Deleter called
Deleter called
Deleter called
Deleter called
Deleter called
[ Carlos, Bob, Birian, Hero, Goat ]
Deleter called
Deleter called
Deleter called
Deleter called

the deleter called is just for debugging purposes in the destructor of the struct I am using to hold val, next, prev

Puwya
  • 41
  • 1
  • 8
  • The only way I can get the move constructor to be called is using std::move but the weird part is no constructor is being called if providing only the temporary object. – Puwya Jul 27 '22 at 17:10
  • 1
    At what point do you believe the move constructor should be called? Also, [mre] please. – Paul Sanders Jul 27 '22 at 17:10
  • @Puwya [`std::move` doesn't actually move anything](https://stackoverflow.com/a/27026280/12002570). And also `std::move` doesn't call the move constructor either. – Jason Jul 27 '22 at 17:13
  • @PaulSanders well I believe any constructor should be called here `HW08::DList list2(list.reverse());` but its not... no constructor is unless I use std::move but my question is shouldn't at least one constructor be called, my guess maybe the copy constructor at the very least. – Puwya Jul 27 '22 at 17:14
  • @Puwya *but none are getting called besides the first object using initializer_list.* -- You should print the value of `this`, not just a simple message. Right now, you have no idea what object is actually being constructed or deleted if you are using the messages you are printing.. – PaulMcKenzie Jul 27 '22 at 17:21
  • `if (this->isEmpty()) throw std::string("Accessing invalid memory");` -- Style issue -- why are you throwing an exception here in `reverse()`? If I am allowed to construct an empty list, I should be able to reverse an empty list (thus the return value will be an empty list). – PaulMcKenzie Jul 27 '22 at 17:23
  • @Puwya the line you ask about in comment - `HW08::DList list2(list.reverse());` will call the constructor `DList(const int &size)`. This can be seen in the body of `reverse()`. – Drew Dormann Jul 27 '22 at 17:26
  • Your right @PaulMcKenzie still doesn't solve the issue but yea I fixed that, also I ran test cases after every instantiation of the objects and the first object is the only one calling a constructor – Puwya Jul 27 '22 at 17:27
  • Yes @DrewDormann but the question is after the temporary object gets returned than what constructor gets called, I have been debugging and while going through it no constructor is called after reverse returns an object. – Puwya Jul 27 '22 at 17:30
  • 1
    @Puwya see [the duplicate](https://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization). No constructor is called after returning, because your compiler knows that you don't need two objects. Only the one object created from `DList(const int &size)`. The `tList` created in `reverse()` is an alias of the `list2` object that you are initializing. – Drew Dormann Jul 27 '22 at 17:38
  • @Puwya -- See the [as-if rule](https://en.cppreference.com/w/cpp/language/as_if). – PaulMcKenzie Jul 27 '22 at 17:42
  • 1
    Ok after going over it I understand wow that was heavy for sure thanks guys – Puwya Jul 27 '22 at 18:17

0 Answers0