-3

I have an object that I want to construct exactly once, because the class it is in keeps track its objects by adding raw pointers to them. Constructing it inline seems to fail though:

// Defined utilities:
ModuleClusterPlot(Type typeArg, const int& layer, const int& module, const int& ladder, const int& startEventArg, const int& endEventArg);
~ModuleClusterPlot();
// Invalid utilities
ModuleClusterPlot(ModuleClusterPlot& t_other) = delete;
ModuleClusterPlot(ModuleClusterPlot&& t_other) = delete;
ModuleClusterPlot& operator=(const ModuleClusterPlot& t_other) = delete;
ModuleClusterPlot& operator=(ModuleClusterPlot&& t_other) = delete;

Calling the constructor via emplace back fails, because it tries to call the move constructor (why?):

moduleClusterPlots.emplace_back(t_type, t_layer, t_module, t_ladder, i, i);

What am I doing wrong here? I am using gcc 7.1.0 wih std=c++14 flag.

Minimal example:

#include <vector>

class ModuleClusterPlot
{
    public:
        enum Type
        {
            foo = 0,
            bar
        };

        ModuleClusterPlot(Type typeArg);
        ~ModuleClusterPlot();
        // Invalid utilities
        ModuleClusterPlot(ModuleClusterPlot& t_other) = delete;
        ModuleClusterPlot(ModuleClusterPlot&& t_other) = delete;
        ModuleClusterPlot& operator=(const ModuleClusterPlot& t_other) = delete;
        ModuleClusterPlot& operator=(ModuleClusterPlot&& t_other) = delete;

};

int main()
{
    std::vector<ModuleClusterPlot> collection;
    collection.emplace_back(ModuleClusterPlot::foo);
}

How can I prevent calling the move constructor here?

Adam Hunyadi
  • 1,890
  • 16
  • 32
  • 5
    Can you make this a [mcve]? – NathanOliver Jul 13 '17 at 11:30
  • You write you want to add `raw pointers` but if you get an error message that a copy/move constructor is needed, I guess you are trying to insert an object instead of just the pointer! – Thomas Sparber Jul 13 '17 at 11:38
  • @ThomasSparber I'm adding `this` to the static object holding the pointers. – Adam Hunyadi Jul 13 '17 at 11:40
  • @AdamHunyadi Ok so please Show the Code and post an MCVE as NathanOliver suggests – Thomas Sparber Jul 13 '17 at 11:41
  • @ThomasSparber I'll do that, my question is more general though, I want to prevent emplace back from calling the move constructor. – Adam Hunyadi Jul 13 '17 at 11:45
  • @NathanOliver Here you are. – Adam Hunyadi Jul 13 '17 at 11:46
  • @AdamHunyadi Well, as soon as you post real Code we can help you... :-) The error is as I said that you don't emplace/push raw pointers but objects! In that case a move or copy constructor is needed. If you declare `std::vector collection` it will work – Thomas Sparber Jul 13 '17 at 11:49
  • @ThomasSparber Yes, but this is the construction of the objects. I am calling the normal constructor via `emplace_back` to create an object, but for some reason the move constructor is invoked too. – Adam Hunyadi Jul 13 '17 at 11:53

2 Answers2

1

std::vector<T>::emplace_back requires a move constructor or copy constructor. The reason is that it might need to reallocate memory and move/copy the existing objects into a new buffer.

Even though you only called it on an empty vector, which wouldn't actually need to move any existing objects, remember that the same function emplace_back can be used on empty and non-empty vectors. The function can't possibly know it's being used from an empty state only, so when the member function is instantiated, the code to deal with a non-empty vector must be valid too.

aschepler
  • 70,891
  • 9
  • 107
  • 161
0

You are violating the constraints of emaplce_back. If we look at table 101 from [sequence.reqmts] we have

Requires: T shall be EmplaceConstructible into X from args. For vector, T shall also be MoveInsertable into X.

emphasis mine

Since your class is not move insertable it will not work with emplace_back.

The reason this is required is because of the size() becomes greater than the capacity() then the vector needs to allocate new storage and move the elements to that new storage. If it can't do that then the vector can't function as intended.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402