1

I have the below bit of code:

map<int,int>& myMap = new map<int,int>();

but I get the following compiler error:

no suitable constructor exists to convert from "std::map<int,int, std::less<int>, std::allocator<std::pair<const int, int>>>*" to "std::map<int,int, std::less<int>, std::allocator<std::pair<const int, int>>>".

Does this mean I have to do:

map<int,int>& myMap = *new map<int,int>();

I thought that objects could passed to references without dereferencing first (as opposed to pointers)? Also I know smart pointers exist but I'm not trying to use those for now.

Fancypants753
  • 429
  • 1
  • 6
  • 19

2 Answers2

8

You can use

map<int,int>& myMap = *new map<int,int>();

but I don't recommend it.

The dynamically allocated memory has to be deallocated. At that time, you will need to use something along the lines of

delete &myMap;

That is poor quality code, IMO.

Use a smart pointer if you need dynamically allocated memory.

std::shared_ptr<map<int,int>> ptr = new map<int,int>();

If you need to use a reference, you can use:

map<int,int>& myMap = *ptr;

It will better if you can avoid dynamically allocated object altogether and use an automatic object (object in stack memory).

map<int,int> myMap;

Update, in response to OP's comment

In a comment you said

Yeah i want to keep that reference because im passing it to a recursive function

The C++ way to deal with it is to pass an object by reference.

void recursive_foo(std::map<int, int>& myMap)
{
}

void foo_user()
{
   std::map<int, int> myMap;
   // Fill up myMap
   // ...

   recursive_foo(myMap);
}

If the recursive function does not modify the object, you can follow the idiom used by the standard library and use iterators instead.

void recursive_foo(std::map<int, int>::iterator start,
                   std::map<int, int>::iterator end)
{
}

void foo_user()
{
   std::map<int, int> myMap;
   // Fill up myMap
   // ...

   recursive_foo(myMap.begin(), myMap.end());
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 1
    I do not think OP needs dynamically allocated memory at all, I bet it came to fix compilation error for `map& myMap;` – Slava Jun 06 '18 at 17:56
  • Yeah i want to keep that reference because im passing it to a recursive function. I can delete it after im done with it. Thanks – Fancypants753 Jun 06 '18 at 18:01
  • 2
    @Fancypants753, that is not sufficient reason to use dynamically allocated object. You can pass an object created on the stack to the recursive function. – R Sahu Jun 06 '18 at 18:03
  • 3
    And I would retain from recommending such code `map& myMap = *new map();` to novice programmer. Later somebody would notice this ugliness and "fix" it with automatic object possibly leaving `delete &myMap;` in the code. Data types should be maintained properly. – Slava Jun 06 '18 at 18:03
  • @RSahu but if I just use pass by value, won't a copy of the value be created during every recursive call? and couldn't that be fixed by just passing a reference? And yes I come from a java heavy background and am trying to come into c++ – Fancypants753 Jun 06 '18 at 18:08
  • 2
    @Fancypants753, don't pass by value. Pass by reference. – R Sahu Jun 06 '18 at 18:09
2

I thought that objects could passed to references without dereferencing first (as opposed to pointers)?

Yes objects can be passed, but what you have here:

map<int,int>& myMap = new map<int,int>();

is not an object but reference which you try to initialize by pointer to dynamically allocated object. Just create object:

map<int,int> myMap;

and it should work fine.

To make things clear, you mixed different concepts, lets say we have a function that accepts variable of sometype by reference:

void func( sometype &ref ) { ... }

it does not mean you have to declare variable as reference to pass it there, you can pass automatic object:

 sometype auto_object;
 func( auto_object );

or pass dynamically allocated one:

 sometype *ptr_to_object = new sometype;
 func( *ptr_to_object );
 delete ptr_to_object; // or better use smart pointer

and if you do not need this object to outlive scope where you use it it is preferable to use first variant.

Slava
  • 43,454
  • 1
  • 47
  • 90
  • so when you create a heap object, does it not give you the value automatically? – Fancypants753 Jun 06 '18 at 18:10
  • 1
    @Fancypants753 `new` returns pointer to object. This pointer can be later dereferenced to be used as "real" object. Instead you can create real object directly but it will live only to the end of scope. Dynamically allocated objects have overhead, but programmer controllable lifetime. Read a textbook C++ is not Java. – Slava Jun 06 '18 at 18:16
  • thanks that really helps. In java I never had to worry about stuff like that but c++ is pretty popular nowadays so I wanted to learn. – Fancypants753 Jun 06 '18 at 18:18