0

Let's say I have a class X that does not have any type of constructor unless an implicit default constructor:

class X
{
  public:
    int value;

    X(void)     = default;

    X(int)      = delete;
    X(const X&) = delete;
    X(X&&)      = delete;
};

When I make a vector out of this, std::vector<X>, and try to push_back(X()) or emplace_back() an element to it, the program will not compile because it tries to use the move constructor (from what I understand of the error description).

C2280 'X::X(X &&)': attempting to reference a deleted function

How can I make push_back or emplace_back use the default constructor?

  • 3
    Resizing would require to move existing elements. – Jarod42 Feb 18 '21 at 12:55
  • 1
    From [std::vector::emplace_back](https://en.cppreference.com/w/cpp/container/vector/emplace_back) "T (the container's element type) must meet the requirements of *MoveInsertable* and *EmplaceConstructible*." – Jarod42 Feb 18 '21 at 12:59
  • @Jarod42 Not if you put an element at the back of a vector though, right? The other elements would stay still (right?) – INEEDANSWERS Feb 18 '21 at 12:59
  • Not when `capacity` is not great enough. and so another bigger buffer is used. – Jarod42 Feb 18 '21 at 13:00
  • @Jarod42 Ah right. So does this mean that when the capacity is too small, the vector tries to reallocate itself elsewhere on the heap? – INEEDANSWERS Feb 18 '21 at 13:01
  • @Jarod42 The capcacity doesn't affect the requirements though. Just to be clear. – eerorika Feb 18 '21 at 13:02
  • 1
    _"the vector tries to reallocate itself elsewhere on the heap?"_ that's implementation defined. The standard doesn't even mention _"heap"_. But the requirements are defined in the standard and one requirement is a copy constructor. – Thomas Sablik Feb 18 '21 at 13:03
  • 1
    "Yes". (and even if your capacity is good enough, code to handle it is still instantiated). – Jarod42 Feb 18 '21 at 13:03
  • What do you mean with "code to handle it is still instantiated"? – INEEDANSWERS Feb 18 '21 at 13:05
  • 2
    Instantiating a class from template `std::vector` generates code containing a call of the copy constructor. Even though you wouldn't call the copy constructor at runtime the compiler or linker will break with an error. C++ is not a script language where code is evaluated at runtime. C++ is compiled and linked and these steps already evaluate the code. – Thomas Sablik Feb 18 '21 at 13:10
  • This is a minimal version of your problem: https://wandbox.org/permlink/dCmRvADoN8CH2MmR `std::vector` requires a copy constructor even though you don't want to call it at runtime. – Thomas Sablik Feb 18 '21 at 13:15
  • You can use a deque or a list instead of a vector. Neither deque nor list require moving elements for `emplace_back`. – dyp Feb 18 '21 at 15:45
  • @dyp Right, of course, I never even thought of that. Thanks! – INEEDANSWERS Feb 18 '21 at 18:59

0 Answers0