0
votes

I'm have a problem with *passing a deleter functor into a std::smart_ptr*. This is the first time I've tried anything like this, so I may be overlooking something very simple..

Here's what my functor class looks like;

#pragma once;
#ifndef ASSETDELETERS_H
#define ASSETDELETERS_H

#include "RenderSystem.h"

struct SourceImageDeleter
{
    RenderSystem & refGraphicsRenderer;
    unsigned int * ptrTextureID;

    explicit SourceImageDeleter( RenderSystem & tempRef, unsigned int * tempPtrID )
        : refGraphicsRenderer( tempRef ) ,
          ptrTextureID(tempPtrID) {};

    SourceImageDeleter( const SourceImageDeleter & originalCopy )
        : refGraphicsRenderer( originalCopy.refGraphicsRenderer ) ,
          ptrTextureID( originalCopy.ptrTextureID ) {};

    void operator() ()
    {
        refGraphicsRenderer.deregisterTexture( ptrTextureID );
    }
};

#endif

The RenderSystem::deregisterTexture function only requires one argument (unsigned int *), because of that, it's being passed at the creation of the functor. I've looked into the use of std::bind, but I don't have much experience with that and wasn't able to have much success using it instead of making a functor.

And here's the only method that uses it so far..

std::shared_ptr<SourceImage> Engine::createSourceImage( std::string tempFilepath )
{
    SourceImage * tempImagePtr = new SourceImage( tempFilepath );

    registerTexture( &tempImagePtr->textureID, &tempImagePtr->image );

    return std::shared_ptr<SourceImage>( tempImagePtr , SourceImageDeleter( this->graphicsRenderer, &tempImagePtr->textureID ) );
}

I'm not sure why it's not working! I've basically been trying to have my smart_ptr run a custom deletion function all week, and between trying to figure out how pointers-to-method passing works, how std::bind/std::mem_fun_ref works, and how functors work has been stumping me all week..

Anyway, here's the compile error that Visual Studio has been giving me, I hope someone can help me figure out what I've been screwing up;

error C2064: term does not evaluate to a function taking 1 arguments
1>          class does not define an 'operator()' or a user defined conversion operator to a pointer-to-function or reference-to-function that takes appropriate number of arguments
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\memory(1438) : see reference to function template instantiation 'void std::tr1::shared_ptr<_Ty>::_Resetp<_Ux,_Dx>(_Ux *,_Dx)' being compiled
1>          with
1>          [
1>              _Ty=SourceImage,
1>              _Ux=SourceImage,
1>              _Dx=SourceImageDeleter
1>          ]
1>          c:\projects\source\engine.cpp(151) : see reference to function template instantiation 'std::tr1::shared_ptr<_Ty>::shared_ptr<SourceImage,SourceImageDeleter>(_Ux *,_Dx)' being compiled
1>          with
1>          [
1>              _Ty=SourceImage,
1>              _Ux=SourceImage,
1>              _Dx=SourceImageDeleter
1>          ]

(By the way, engine.cpp(151) is the return line inside Engine::createSourceImage shown above.. If I remove the deleter argument, the program compiles and runs fine aside from the obvious resource leaks associated with improper image deletion..)

1

1 Answers

2
votes

std::shared_ptr passes in the pointer being deleted to the deleter, which is exactly what your error message says: the class does not define an operator() with the correct number of arguments.

Your deleter isn't expecting any parameters, so it won't work; you'll need to change it to void operator()(SourceImage*)