0

Some older versions of required a complete definition of the type for default_deleter to be defined. (I know this was the case in Visual Studio 2012 but I'd give bonus points to anyone who could tell me which version remedied this.)

To work around this I can write a custom_deleter function like so:

template <typename T>
void custom_deleter(T* param) {
    delete param;
}

And declare a smart pointer on a forward declared type like so: unique_ptr<Foo, function<void(Foo*)>> pFoo, assigning this pointer where Foo was completely declared like so: pFoo = decltype(pFoo)(new Foo, function(custom_deleter<Foo>))

Now as suggested here, I'd like to make my custom_deleter into a functor like this:

struct MyDeleter {
    template <typename T>
    void operator ()(T* param) {
        delete param;
    }
};

Which should allow me to declare: unique_ptr<Foo, MyDeleter> and assign: pFoo = decltype(pFoo)(new Foo) However when I try to do this in I get:

warning C4150: deletion of pointer to incomplete type Foo; no destructor called

Is there a way I can work around this as well?

Live Example

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • I think you need to provide a minimal complete example that shows how you want your custom deleter to be used. I'm sure you're aware of how the basic idea here is to make sure the `delete` expression is not instantiated until the type is complete. But if we don't see the code then we can't comment on how to achieve that. – Brian Bi Sep 19 '19 at 13:41
  • @Brian Because this requires forward declaration, even a minimum example is a lot of code. I've hacked the smallest one I could think of together and added a link to the bottom of the question. I'm a little surprised after writing this that it seems that the warning is not unique to Visual Studio 2012, but even modern gcc is giving me that warning. So maybe this is just a thing? And maybe there's a workaround? – Jonathan Mee Sep 19 '19 at 14:26
  • 1
    The issue here is that the implicitly defined default constructor of `Bar` will odr-use the destructor of the `unique_ptr` member. You can fix this by declaring the default constructor of `Bar` and then defining it as defaulted in `bar.cpp`. See the linked duplicate. – Brian Bi Sep 19 '19 at 14:46
  • 1
    Sorry, forgot to say - both the constructor and the destructor have to be forward-declared in this way. I forgot to mention the destructor because it's obvious. But if you only forward-declare the destructor and not the constructor, it still won't work. – Brian Bi Sep 19 '19 at 15:02
  • @Brian So I think the answer that you intended me to get out of that was in the question not the answer right? Just define the constructor and destructor in the implementation where `Foo` is defined, right? That does seem to solve the problem. So thank you for pointing me to the solution. I'm not certain I agree they're duplicates, I'm more asking, "How do I solve this?" And he's asking, "Why does this solution work?" – Jonathan Mee Sep 19 '19 at 15:17
  • 1
    I don't know exactly what the SO policy is on duplicates, but this seems like a case where the community would *usually* mark the question as a duplicate even though it's not really asking the same thing. But since you pointed this out, I'll reopen it and see if other people want to close it. – Brian Bi Sep 19 '19 at 15:19

0 Answers0