1

Is there a way to use make_unique and pass the output of a function as a parameter?

auto loadedSurface1 = std::unique_ptr<SDL_Surface,SurfaceDeleter>(IMG_Load(path.c_str()));
auto loadedSurface2 = std::make_unique<SDL_Surface, SurfaceDeleter>();
loadedSurface2.reset(IMG_Load(path.c_str()));
auto loadedSurface3 = std::make_unique<SDL_Surface, SurfaceDeleter>(IMG_Load(path.c_str())));

SurfaceDeleter is a functor.

loadedSurface1 and loadedSurface2 both work fine. loadedSurface3 fails ( no instance of overloaded function matches the argument list)

If there's no way to make loadedSurface3 work, is loadedSurface2 recommended over loadedSurface1 because it uses make_unique?

user250095
  • 13
  • 3
  • 2
    What do you mean when you say it "fails"? What happens exactly? Present a [MCVE]. – Lightness Races in Orbit May 03 '19 at 09:24
  • 2
    How does it fail? Elaborate please. – πάντα ῥεῖ May 03 '19 at 09:25
  • 1
    When you do `std::make_unique` you are not specifying the type of the deleter of the `unique_ptr`, but specifying that `SurfaceDeleter` is the type of the first argument to `std::make_unique`. You cannot use `std::make_unique` to create a `unique_ptr` with a custom deleter. Compare with the [declaration of `make_unique`](https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique). – nwp May 03 '19 at 09:27
  • Why are you answering in comments :( – Lightness Races in Orbit May 03 '19 at 09:28
  • @LightnessRacesinOrbit Our understanding of what an answer is differs. Neither my comment nor your answer answer the question. – nwp May 03 '19 at 09:32
  • `path.c_str` looks extremely suspicious. `std::string::c_str()` is a function. Now other objects theoretically can have a data member with the same name, but the convention definitely is that `c_str` is a function returning a C-style null-terminated string, even on other classes. – MSalters May 03 '19 at 11:54
  • Whoops, you are 100% right. I'll edit my question. – user250095 May 05 '19 at 02:14

1 Answers1

4

Is there a way to use make_unique and pass the output of a function as a parameter?

std::make_unique<T> takes constructor arguments to create a new T. It does not take a T* to an existing T.

Furthermore, you can't specify a deleter with it like that.

You mean simply:

std::unique_ptr<SDL_Surface, SurfaceDeleter> loadedSurface3{IMG_Load(path.c_str())};

is loadedSurface2 recommended over loadedSurface1 because it uses make_unique?

I can't see any benefit there. All you've achieved is to split your construction over two lines and lose the deleter.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055