【问题标题】:Using std::bind with overloaded methods in namespace in C++在 C++ 命名空间中使用 std::bind 和重载方法
【发布时间】:2021-12-04 22:29:36
【问题描述】:
#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;
}

我正在尝试在 Photon 类的命名空间 EgammaParameters 中绑定一个重载的方法(测试)。据我了解,我需要专门告诉 C++ 它应该使用哪个重载方法,所以我尝试使用静态转换,如:

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

但是,这给了我错误error: invalid static_cast from type ‘’ to type ‘double (&amp;)(xAOD::EgammaParameters::ShowerShapeType)。我错过了什么?

【问题讨论】:

    标签: c++ overloading bind static-cast


    【解决方案1】:

    使用 lambda 更容易:

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

    如果你真的想使用绑定:

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

    我建议至少有一个助手别名:

    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);
    

    从 C++20 开始,我建议将 std::bind 替换为 std::bind_front

    【讨论】:

    • 有时当模板参数变得如此复杂时,我会通过为不同部分创建 typedef 来调试它。这个表达式相当复杂!
    • 1 个问题:const EgammaParameters::ShowerShapeType information 中的“const”实际上是多余的吗?无论如何,参数都是按值传递的。这就是为什么您的模板在xAOD::EgammaParameters::ShowerShapeType 前面没有“const”的原因吗?
    • @roccobaroccoSC 是的。声明 void foo(int)void foo(const int) 是相同的。这里的const 只用在函数体(定义)中。在声明中(函数类型)被忽略。 static_assert(std::is_same_v&lt;int(int), int(const int)&gt;);.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多