Home > Software design >  Using std::bind with overloaded methods in namespace in C
Using std::bind with overloaded methods in namespace in C

Time:12-05

#include <iostream>
#include <map>
#include <functional>


namespace xAOD{
  
    
    namespace EgammaParameters{
        
        enum ShowerShapeType{
             var1 = 0,
             var2 = 1,
             var3 = 3
        };
    };
    
    class Photon{
        public:
        
            // I don't want to use this overload
            //double test(float& value, const EgammaParameters::ShowerShapeType information) const {return 1;}
            // I want to use this overload
            double test(const EgammaParameters::ShowerShapeType information) const {return 1;}

        private:

    };
    
};


struct funcLookup
{
    funcLookup(xAOD::Photon * photon)
    {
        //this works without the first overload
        lookup_callback["test"] = std::bind(&xAOD::Photon::test, photon, xAOD::EgammaParameters::ShowerShapeType::var1);
        // static casting doesn't work:
       //lookup_callback["test"] = std::bind(static_cast<double(&)(const xAOD::EgammaParameters::ShowerShapeType)>(&xAOD::Photon::test), photon,xAOD::EgammaParameters::ShowerShapeType::var1);

    }

    double call(std::string name)
    {
        if (lookup_callback.count(name) > 0){
            return lookup_callback[name]();
        }
        else{
            
            std::cerr << "Invalid Function Call "<< std::endl;
            return -1;
        } 
    }
    std::map<std::string, std::function<double(void)>> lookup_callback;
};
    
int main()
{

    xAOD::Photon * photon;
    funcLookup funcMap(photon);
    std::cout<<funcMap.call("test")<<std::endl;


    return 0;
}

I am trying to bind a method (test) which is overload in a namespace EgammaParameters in the class Photon. As far as I understand, I need to specifically tell C which overloaded method it should use, so I tried to use static casting like:

std::bind(static_cast<double(&)(const xAOD::EgammaParameters::ShowerShapeType)>(&xAOD::Photon::test), photon,xAOD::EgammaParameters::ShowerShapeType::var1);

However, this gives me the error error: invalid static_cast from type ‘’ to type ‘double (&)(xAOD::EgammaParameters::ShowerShapeType). What am I missing?

CodePudding user response:

Using lambda is easier:

lookup_callback["test"] = [=] {
     return photon->test(xAOD::EgammaParameters::ShowerShapeType::var1);
};

If you really want to use bind:

lookup_callback["test"] = std::bind(
    static_cast<double (xAOD::Photon::*)
                (xAOD::EgammaParameters::ShowerShapeType) const>( 
                    &xAOD::Photon::test),
    photon,
    xAOD::EgammaParameters::ShowerShapeType::var1);

And I would suggest at least a helper alias:

using TestType
    = double (xAOD::Photon::*) (xAOD::EgammaParameters::ShowerShapeType) const;

lookup_callback["test"] = std::bind(
    static_cast<TestType>(&xAOD::Photon::test),
    photon,
    xAOD::EgammaParameters::ShowerShapeType::var1);

And since C 20 I would suggest replacing std::bind with std::bind_front.

  • Related