10

I have an object that I want to restrict to be allocated only inside of a std::map. Here is the simplified code:

#include <map>

class Value
{
public:
    Value(int value) { _value = value;}
    Value(const Value&) = delete;
    Value& operator=(const Value&) = delete;
    Value(Value&&) = default;     // ***
    void* operator new(size_t) = delete;    // not on free store
private:
    int _value;
};

class Container
{    
public:
    Container();
    Value* addToMap(int key) {
        auto ret = _map.emplace(key, key);
        return &(ret.first->second);
    }
private:
    std::map<int, Value> _map;
};

In order to make it compile on Mac using CLang I had to add a line marked by asterisks requesting default move constructor. However this line causes C2610 error when compiled in Windows Visual Studio. Looks like VS2013 C++11 non-compliance includes inability to generate default move constructors. Is there a different way for me to allocate an object inside of standard map that would compile across platforms or do I have to implement my own move constructor?

Piotr Skotnicki
  • 46,953
  • 7
  • 118
  • 160
LRaiz
  • 667
  • 7
  • 18
  • Why do you want to add this restriction? – Neil Kirk Oct 13 '14 at 16:33
  • I want the object to be owned exclusively by container and prevent other code from calling new and delete. – LRaiz Oct 13 '14 at 17:36
  • You are mixing objects and data structures. If user of your data structure wants to copy the object, why not? – Neil Kirk Oct 13 '14 at 17:46
  • The nature of my objects is such that I don't want them to be uncontrollably copyable or movable. I have a network of mutually dependent objects of several types and in order to enforce validity of network topology I need to limit the way how objects are brought to life and destroyed. In some sense my reasons are similar to reasons why people want to use unique_ptr to store their data. – LRaiz Oct 13 '14 at 17:53

1 Answers1

9

An option is to use std::piecewise_construct:

Value* addToMap(int key) {
    auto ret = _map.emplace(std::piecewise_construct
                          , std::forward_as_tuple(key)
                          , std::forward_as_tuple(key));
    return &(ret.first->second);
}

VC++ DEMO

Piotr Skotnicki
  • 46,953
  • 7
  • 118
  • 160