Can I call a virtual destructor using a function pointer?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
6
down vote

favorite












I have class Data which can hold a pointer to an object. I want to be able to call its destructor manually later on, for which I need its address stored in a variable but it seems that taking the address of constructor/destructor is forbidden. Is there any way around this ?



struct Data {

union
long i;
float f;
void* data_ptr;
_data;

std::type_index _typeIndex;
void (*_destructor_ptr)();

template<typename T>
void Init()
if constexpr (std::is_integral<T>::value)
//

else if constexpr (std::is_floating_point<T>::value)
//

else
_data.data_ptr = new T;
_typeIndex = std::type_index(typeid(T));
_destructor_ptr = &T::~T; // << -- can't do this











share|improve this question









New contributor




const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



















  • stackoverflow.com/questions/7905272/… ?
    – Kamil Cuk
    4 hours ago






  • 5




    Just to clarify, what's stopping you from calling delete ?
    – Praneeth Peiris
    4 hours ago










  • @PraneethPeiris - delete on what?
    – StoryTeller
    4 hours ago






  • 2




    An alternate was of destructing an arbitrary type is having a shared_ptr<void> which you can assign any newd type to and it will remember how to destruct it whilst keeping your code from having to remember the type.
    – Mike Vine
    3 hours ago










  • @PraneethPeiris delete on a void* will not call the destructor
    – const_iterator
    3 hours ago














up vote
6
down vote

favorite












I have class Data which can hold a pointer to an object. I want to be able to call its destructor manually later on, for which I need its address stored in a variable but it seems that taking the address of constructor/destructor is forbidden. Is there any way around this ?



struct Data {

union
long i;
float f;
void* data_ptr;
_data;

std::type_index _typeIndex;
void (*_destructor_ptr)();

template<typename T>
void Init()
if constexpr (std::is_integral<T>::value)
//

else if constexpr (std::is_floating_point<T>::value)
//

else
_data.data_ptr = new T;
_typeIndex = std::type_index(typeid(T));
_destructor_ptr = &T::~T; // << -- can't do this











share|improve this question









New contributor




const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



















  • stackoverflow.com/questions/7905272/… ?
    – Kamil Cuk
    4 hours ago






  • 5




    Just to clarify, what's stopping you from calling delete ?
    – Praneeth Peiris
    4 hours ago










  • @PraneethPeiris - delete on what?
    – StoryTeller
    4 hours ago






  • 2




    An alternate was of destructing an arbitrary type is having a shared_ptr<void> which you can assign any newd type to and it will remember how to destruct it whilst keeping your code from having to remember the type.
    – Mike Vine
    3 hours ago










  • @PraneethPeiris delete on a void* will not call the destructor
    – const_iterator
    3 hours ago












up vote
6
down vote

favorite









up vote
6
down vote

favorite











I have class Data which can hold a pointer to an object. I want to be able to call its destructor manually later on, for which I need its address stored in a variable but it seems that taking the address of constructor/destructor is forbidden. Is there any way around this ?



struct Data {

union
long i;
float f;
void* data_ptr;
_data;

std::type_index _typeIndex;
void (*_destructor_ptr)();

template<typename T>
void Init()
if constexpr (std::is_integral<T>::value)
//

else if constexpr (std::is_floating_point<T>::value)
//

else
_data.data_ptr = new T;
_typeIndex = std::type_index(typeid(T));
_destructor_ptr = &T::~T; // << -- can't do this











share|improve this question









New contributor




const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I have class Data which can hold a pointer to an object. I want to be able to call its destructor manually later on, for which I need its address stored in a variable but it seems that taking the address of constructor/destructor is forbidden. Is there any way around this ?



struct Data {

union
long i;
float f;
void* data_ptr;
_data;

std::type_index _typeIndex;
void (*_destructor_ptr)();

template<typename T>
void Init()
if constexpr (std::is_integral<T>::value)
//

else if constexpr (std::is_floating_point<T>::value)
//

else
_data.data_ptr = new T;
_typeIndex = std::type_index(typeid(T));
_destructor_ptr = &T::~T; // << -- can't do this








c++ explicit-destructor-call






share|improve this question









New contributor




const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 1 hour ago





















New contributor




const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 4 hours ago









const_iterator

837




837




New contributor




const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











  • stackoverflow.com/questions/7905272/… ?
    – Kamil Cuk
    4 hours ago






  • 5




    Just to clarify, what's stopping you from calling delete ?
    – Praneeth Peiris
    4 hours ago










  • @PraneethPeiris - delete on what?
    – StoryTeller
    4 hours ago






  • 2




    An alternate was of destructing an arbitrary type is having a shared_ptr<void> which you can assign any newd type to and it will remember how to destruct it whilst keeping your code from having to remember the type.
    – Mike Vine
    3 hours ago










  • @PraneethPeiris delete on a void* will not call the destructor
    – const_iterator
    3 hours ago
















  • stackoverflow.com/questions/7905272/… ?
    – Kamil Cuk
    4 hours ago






  • 5




    Just to clarify, what's stopping you from calling delete ?
    – Praneeth Peiris
    4 hours ago










  • @PraneethPeiris - delete on what?
    – StoryTeller
    4 hours ago






  • 2




    An alternate was of destructing an arbitrary type is having a shared_ptr<void> which you can assign any newd type to and it will remember how to destruct it whilst keeping your code from having to remember the type.
    – Mike Vine
    3 hours ago










  • @PraneethPeiris delete on a void* will not call the destructor
    – const_iterator
    3 hours ago















stackoverflow.com/questions/7905272/… ?
– Kamil Cuk
4 hours ago




stackoverflow.com/questions/7905272/… ?
– Kamil Cuk
4 hours ago




5




5




Just to clarify, what's stopping you from calling delete ?
– Praneeth Peiris
4 hours ago




Just to clarify, what's stopping you from calling delete ?
– Praneeth Peiris
4 hours ago












@PraneethPeiris - delete on what?
– StoryTeller
4 hours ago




@PraneethPeiris - delete on what?
– StoryTeller
4 hours ago




2




2




An alternate was of destructing an arbitrary type is having a shared_ptr<void> which you can assign any newd type to and it will remember how to destruct it whilst keeping your code from having to remember the type.
– Mike Vine
3 hours ago




An alternate was of destructing an arbitrary type is having a shared_ptr<void> which you can assign any newd type to and it will remember how to destruct it whilst keeping your code from having to remember the type.
– Mike Vine
3 hours ago












@PraneethPeiris delete on a void* will not call the destructor
– const_iterator
3 hours ago




@PraneethPeiris delete on a void* will not call the destructor
– const_iterator
3 hours ago












2 Answers
2






active

oldest

votes

















up vote
5
down vote



accepted










Store a lambda, suitably converted:



void (*_destructor_ptr)(void *v);

// ...

_destructor_ptr = +(void* v) delete static_cast<T*>(v); ;


Note that you must pass _data.data_ptr for v. If you intend to store a plain function pointer, the lambda may not capture or implicitly refer to _data.data_ptr.






share|improve this answer
















  • 1




    Why do you need the + sign before the lambda ?
    – const_iterator
    2 hours ago







  • 1




    @const_iterator for the plus sign see this one here stackoverflow.com/questions/17822131/…
    – Myz
    2 hours ago







  • 1




    @const_iterator - Sorcery to force coercion into a pointer. It's not really needed here, the assignment itself would do it. But at times you want to ensure it happens, and it's a bit out of force of habit for me.
    – StoryTeller
    2 hours ago






  • 1




    @const_iterator - You get a unique lambda type for each type, not for each object. Converting it to a function pointer also produces one function per type. You can go the more verbose route, but it doesn't gain you anything here. If you like the more descriptive name of the custom struct, then by all means.
    – StoryTeller
    1 hour ago







  • 2




    @const_iterator - Also, if you produced an alternative answer to your question, it belongs in the answer section, not as an edit to your post. You can even accept it instead if you wish. It's how SO is meant to work.
    – StoryTeller
    1 hour ago

















up vote
5
down vote













There's also this solution if your compiler doesn't support lambdas:



template<typename T>
struct DestructorHelper
static void Destroy(void * v)
delete static_cast<T*>(v);

;


and use it as:



_destructor_ptr = &DestructorHelper<T>::Destroy;





share|improve this answer








New contributor




const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

















    Your Answer





    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );






    const_iterator is a new contributor. Be nice, and check out our Code of Conduct.









     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52737451%2fcan-i-call-a-virtual-destructor-using-a-function-pointer%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    5
    down vote



    accepted










    Store a lambda, suitably converted:



    void (*_destructor_ptr)(void *v);

    // ...

    _destructor_ptr = +(void* v) delete static_cast<T*>(v); ;


    Note that you must pass _data.data_ptr for v. If you intend to store a plain function pointer, the lambda may not capture or implicitly refer to _data.data_ptr.






    share|improve this answer
















    • 1




      Why do you need the + sign before the lambda ?
      – const_iterator
      2 hours ago







    • 1




      @const_iterator for the plus sign see this one here stackoverflow.com/questions/17822131/…
      – Myz
      2 hours ago







    • 1




      @const_iterator - Sorcery to force coercion into a pointer. It's not really needed here, the assignment itself would do it. But at times you want to ensure it happens, and it's a bit out of force of habit for me.
      – StoryTeller
      2 hours ago






    • 1




      @const_iterator - You get a unique lambda type for each type, not for each object. Converting it to a function pointer also produces one function per type. You can go the more verbose route, but it doesn't gain you anything here. If you like the more descriptive name of the custom struct, then by all means.
      – StoryTeller
      1 hour ago







    • 2




      @const_iterator - Also, if you produced an alternative answer to your question, it belongs in the answer section, not as an edit to your post. You can even accept it instead if you wish. It's how SO is meant to work.
      – StoryTeller
      1 hour ago














    up vote
    5
    down vote



    accepted










    Store a lambda, suitably converted:



    void (*_destructor_ptr)(void *v);

    // ...

    _destructor_ptr = +(void* v) delete static_cast<T*>(v); ;


    Note that you must pass _data.data_ptr for v. If you intend to store a plain function pointer, the lambda may not capture or implicitly refer to _data.data_ptr.






    share|improve this answer
















    • 1




      Why do you need the + sign before the lambda ?
      – const_iterator
      2 hours ago







    • 1




      @const_iterator for the plus sign see this one here stackoverflow.com/questions/17822131/…
      – Myz
      2 hours ago







    • 1




      @const_iterator - Sorcery to force coercion into a pointer. It's not really needed here, the assignment itself would do it. But at times you want to ensure it happens, and it's a bit out of force of habit for me.
      – StoryTeller
      2 hours ago






    • 1




      @const_iterator - You get a unique lambda type for each type, not for each object. Converting it to a function pointer also produces one function per type. You can go the more verbose route, but it doesn't gain you anything here. If you like the more descriptive name of the custom struct, then by all means.
      – StoryTeller
      1 hour ago







    • 2




      @const_iterator - Also, if you produced an alternative answer to your question, it belongs in the answer section, not as an edit to your post. You can even accept it instead if you wish. It's how SO is meant to work.
      – StoryTeller
      1 hour ago












    up vote
    5
    down vote



    accepted







    up vote
    5
    down vote



    accepted






    Store a lambda, suitably converted:



    void (*_destructor_ptr)(void *v);

    // ...

    _destructor_ptr = +(void* v) delete static_cast<T*>(v); ;


    Note that you must pass _data.data_ptr for v. If you intend to store a plain function pointer, the lambda may not capture or implicitly refer to _data.data_ptr.






    share|improve this answer












    Store a lambda, suitably converted:



    void (*_destructor_ptr)(void *v);

    // ...

    _destructor_ptr = +(void* v) delete static_cast<T*>(v); ;


    Note that you must pass _data.data_ptr for v. If you intend to store a plain function pointer, the lambda may not capture or implicitly refer to _data.data_ptr.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered 4 hours ago









    StoryTeller

    84.7k12171237




    84.7k12171237







    • 1




      Why do you need the + sign before the lambda ?
      – const_iterator
      2 hours ago







    • 1




      @const_iterator for the plus sign see this one here stackoverflow.com/questions/17822131/…
      – Myz
      2 hours ago







    • 1




      @const_iterator - Sorcery to force coercion into a pointer. It's not really needed here, the assignment itself would do it. But at times you want to ensure it happens, and it's a bit out of force of habit for me.
      – StoryTeller
      2 hours ago






    • 1




      @const_iterator - You get a unique lambda type for each type, not for each object. Converting it to a function pointer also produces one function per type. You can go the more verbose route, but it doesn't gain you anything here. If you like the more descriptive name of the custom struct, then by all means.
      – StoryTeller
      1 hour ago







    • 2




      @const_iterator - Also, if you produced an alternative answer to your question, it belongs in the answer section, not as an edit to your post. You can even accept it instead if you wish. It's how SO is meant to work.
      – StoryTeller
      1 hour ago












    • 1




      Why do you need the + sign before the lambda ?
      – const_iterator
      2 hours ago







    • 1




      @const_iterator for the plus sign see this one here stackoverflow.com/questions/17822131/…
      – Myz
      2 hours ago







    • 1




      @const_iterator - Sorcery to force coercion into a pointer. It's not really needed here, the assignment itself would do it. But at times you want to ensure it happens, and it's a bit out of force of habit for me.
      – StoryTeller
      2 hours ago






    • 1




      @const_iterator - You get a unique lambda type for each type, not for each object. Converting it to a function pointer also produces one function per type. You can go the more verbose route, but it doesn't gain you anything here. If you like the more descriptive name of the custom struct, then by all means.
      – StoryTeller
      1 hour ago







    • 2




      @const_iterator - Also, if you produced an alternative answer to your question, it belongs in the answer section, not as an edit to your post. You can even accept it instead if you wish. It's how SO is meant to work.
      – StoryTeller
      1 hour ago







    1




    1




    Why do you need the + sign before the lambda ?
    – const_iterator
    2 hours ago





    Why do you need the + sign before the lambda ?
    – const_iterator
    2 hours ago





    1




    1




    @const_iterator for the plus sign see this one here stackoverflow.com/questions/17822131/…
    – Myz
    2 hours ago





    @const_iterator for the plus sign see this one here stackoverflow.com/questions/17822131/…
    – Myz
    2 hours ago





    1




    1




    @const_iterator - Sorcery to force coercion into a pointer. It's not really needed here, the assignment itself would do it. But at times you want to ensure it happens, and it's a bit out of force of habit for me.
    – StoryTeller
    2 hours ago




    @const_iterator - Sorcery to force coercion into a pointer. It's not really needed here, the assignment itself would do it. But at times you want to ensure it happens, and it's a bit out of force of habit for me.
    – StoryTeller
    2 hours ago




    1




    1




    @const_iterator - You get a unique lambda type for each type, not for each object. Converting it to a function pointer also produces one function per type. You can go the more verbose route, but it doesn't gain you anything here. If you like the more descriptive name of the custom struct, then by all means.
    – StoryTeller
    1 hour ago





    @const_iterator - You get a unique lambda type for each type, not for each object. Converting it to a function pointer also produces one function per type. You can go the more verbose route, but it doesn't gain you anything here. If you like the more descriptive name of the custom struct, then by all means.
    – StoryTeller
    1 hour ago





    2




    2




    @const_iterator - Also, if you produced an alternative answer to your question, it belongs in the answer section, not as an edit to your post. You can even accept it instead if you wish. It's how SO is meant to work.
    – StoryTeller
    1 hour ago




    @const_iterator - Also, if you produced an alternative answer to your question, it belongs in the answer section, not as an edit to your post. You can even accept it instead if you wish. It's how SO is meant to work.
    – StoryTeller
    1 hour ago












    up vote
    5
    down vote













    There's also this solution if your compiler doesn't support lambdas:



    template<typename T>
    struct DestructorHelper
    static void Destroy(void * v)
    delete static_cast<T*>(v);

    ;


    and use it as:



    _destructor_ptr = &DestructorHelper<T>::Destroy;





    share|improve this answer








    New contributor




    const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.





















      up vote
      5
      down vote













      There's also this solution if your compiler doesn't support lambdas:



      template<typename T>
      struct DestructorHelper
      static void Destroy(void * v)
      delete static_cast<T*>(v);

      ;


      and use it as:



      _destructor_ptr = &DestructorHelper<T>::Destroy;





      share|improve this answer








      New contributor




      const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.



















        up vote
        5
        down vote










        up vote
        5
        down vote









        There's also this solution if your compiler doesn't support lambdas:



        template<typename T>
        struct DestructorHelper
        static void Destroy(void * v)
        delete static_cast<T*>(v);

        ;


        and use it as:



        _destructor_ptr = &DestructorHelper<T>::Destroy;





        share|improve this answer








        New contributor




        const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        There's also this solution if your compiler doesn't support lambdas:



        template<typename T>
        struct DestructorHelper
        static void Destroy(void * v)
        delete static_cast<T*>(v);

        ;


        and use it as:



        _destructor_ptr = &DestructorHelper<T>::Destroy;






        share|improve this answer








        New contributor




        const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        share|improve this answer



        share|improve this answer






        New contributor




        const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        answered 1 hour ago









        const_iterator

        837




        837




        New contributor




        const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.





        New contributor





        const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.






        const_iterator is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.




















            const_iterator is a new contributor. Be nice, and check out our Code of Conduct.









             

            draft saved


            draft discarded


















            const_iterator is a new contributor. Be nice, and check out our Code of Conduct.












            const_iterator is a new contributor. Be nice, and check out our Code of Conduct.











            const_iterator is a new contributor. Be nice, and check out our Code of Conduct.













             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52737451%2fcan-i-call-a-virtual-destructor-using-a-function-pointer%23new-answer', 'question_page');

            );

            Post as a guest













































































            Comments

            Popular posts from this blog

            White Anglo-Saxon Protestant

            Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

            One-line joke