0

In my .h file I define the following container:

std::vector< std::map< std::string, const std::unique_ptr < std::vector<double> > > > loaded_data;

When I try to allocate memory or resize it in the .cpp file, using :

loaded_data.reserve(100);

or:

loaded_data.resize(100);

I get the following error:

/usr/include/c++/7.4.0/ext/new_allocator.h(136): error: function "std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2> &) [with _T1=const std::__cxx11::string, _T2=const std::unique_ptr>, std::default_delete>>>]" (declared at line 303 of "/usr/include /c++/7.4.0/bits/stl_pair.h") cannot be referenced -- it is a deleted function

I do not understand why the constructor for such a pair would be deleted.

When I dot the same with similar objects, such as:

std::map < Variables,std::map<size_t, const std::unique_ptr < std::vector < std::vector<double> > > > >

I don't have any problem with reserve. Note that this issue does not arise with older C++ container libraries.

Does anyone know why I have this error and which workaround could work?

Thanks

Chelmy88
  • 1,106
  • 1
  • 6
  • 17
  • Did you want `const std::unique_ptr` or `std::unique_ptr`? Using the former produces a map with a `const` value type. While I'm not sure of the consequences of that, I can't imagine it is helping the situation. – François Andrieux Sep 05 '19 at 14:28
  • I want `const std::unique_ptr`, since I won't modify what it points to – Chelmy88 Sep 05 '19 at 14:29
  • 1
    @Chelmy88 It seems your comment was ambiguous. Modify what it points to can both mean modify the object at the pointed address and modify which object it currently points to. – François Andrieux Sep 05 '19 at 14:32
  • To clarify, I want to be able to modify the vector(s) inside the pointer, but the pointer will always point to the same vector – Chelmy88 Sep 05 '19 at 14:34
  • Regardless of applicability of `const shared_ptr`, the example provided compiles correctly. VTC and downvote for the lack of effort in providing [mcve]. – SergeyA Sep 05 '19 at 14:34
  • [Works in gcc but not VC++](https://godbolt.org/z/j5_4LB). Likely an implementation bug where it's not using the move semantics and trying to copy instead. Possibly due to a missing `noexcept` specifier? – François Andrieux Sep 05 '19 at 14:34
  • @SergeyA As I said in some OS and compilers version there is no problem. I get this issue with `icpc (ICC) 19.0.1.144 20181018` on Linux, no issue with gcc or with icpc on mac os – Chelmy88 Sep 05 '19 at 14:36
  • 2
    @Chelmy88 Removing the `unique_ptr` solves the problem. Since it's a `unique_ptr` it shows unique ownership and since it's `const` it always owns the same `vector`. That seems to me to be equivalent to just using `std::vector` directly. I'd be curious to know the benefit you see in `const std::unique_ptr` over `std::vector`. Otherwise, get ride of the `unique_ptr`. You get a simpler design and it eliminates the compiler error. – François Andrieux Sep 05 '19 at 14:37
  • I would recommend reconsidering using such an extensive container type. Consider future developers (including your future self). Such a type is very unintuitive, it can be very hard to understand the intention behind it without extensive documentation. Even just creating alias for each step of it's declaration would help document what the container is supposed to mean. – François Andrieux Sep 05 '19 at 14:42
  • 1
    I suspect a duplicate of https://stackoverflow.com/q/53527682/3953764 – Piotr Skotnicki Sep 05 '19 at 14:43
  • @FrançoisAndrieux Yes I could get ride of the pointer, I introduced them because I had performance issues when the object was becoming large. I know that this is not a really clear implementation, what would you recommend to do to store large data which should be accessed in a nested way (the first vector is for various locations, and the map for various variables) – Chelmy88 Sep 05 '19 at 14:48
  • Unique Pointers cannot be copied, only moved. That's why the method is missing. – U. W. Sep 05 '19 at 14:48
  • @U.W. But why I do not get the error in the `map<...,map<..,unique_ptr>>`? Because in vectors element can be moved in memory later whihc is not the cas in maps? – Chelmy88 Sep 05 '19 at 14:50
  • @Chelmy88 It's probably not strictly required to be allowed, and you just got unlucky up to now. At least, that's what I gather from the proposed duplicate. Edit : Elements don't move around in a `map`, so you wouldn't see this problem. – François Andrieux Sep 05 '19 at 14:51
  • 2
    @Chelmy88 It's hard to imagine why `std::unique_ptr` would help performance here. Did you measure a gain? It adds an indirection which generally is not performance friendly. And the size of the map's elements shouldn't have an impact, as far as I can tell. If you have problems when your map gets too big, consider `unordered_map` instead. – François Andrieux Sep 05 '19 at 14:53
  • This `unique_ptr` is obsoleate and doesn't provide any extra functionality. IMO you should just use: `std::vector > > loaded_data;`. Use of `std::unique_ptr` inside a `std::vector` has seance only when polymorphism is used in all other cases value should be used. – Marek R Sep 05 '19 at 14:56
  • @Marek R: You might want to brush up on your nowledge what unique_ptr is and what it does. If that is "no extra functionality" for you, then I think you are wrong. – U. W. Sep 09 '19 at 07:58
  • @U.W. the only extra functionality `unique_ptr` provides here is extra overhead (extra heap allocations and heap allocations). Oh sorry, I forgot, it also makes this map harder to maintain. – Marek R Sep 09 '19 at 09:18

0 Answers0