提升Mem_fn并访问派生类的成员函数

时间:2016-05-10 20:22:29

标签: boost bind derived-class

我做了一个简单的例子来测试boost bind与派生类的交互。

我创建了两个具有不同getarea函数的子类。我期待

g1 = boost::bind(boost::mem_fn(&Shape::getarea), Rec) 

打印矩形区域(10,20)但是打印了#1;'。当我改为写Rectangle::getarea时,我也会这样做。即使我输入其他功能,它也会打印相同的内容。矩形的成员

double sum(double h,double w){return h+w;   }

并使用

 g1 = boost::bind(boost::mem_fn(&Rectangle::sum), Rec,2,3) 

问题1:为什么会返回' 1'?这是错误的默认响应吗?

我的第二个问题是执行相同的打印g2,但现在Rec被** iter替换,即来自对象列表的某些派生类类型的对象。由于getarea是一个虚拟的fcn,一旦我完成上述工作,只需写下来就可以了:

g2= boost::bind(boost::mem_fn(& Shape::getarea , &(**iter)); 

问题2:但是,我想知道是否有办法返回** iter的classtype例如。 classof(** iter)然后把它放在g2中,即

g2= boost::bind(boost::mem_fn(& classof(**iter)::getarea , &(**iter)); 

当我通过编写Shape :: getarea来运行g2时,我得到了' 1'再次为所有人。

   #include <memory>
    #include <vector>
    #include <string>
    #include <iostream>
    #include <sstream>
    #include <boost/bind.hpp>
    using namespace std;

    class Shape {
        public:    
            Shape(double h, double w) :height(h), width(w) {};
            virtual double getarea() = 0;
            double height;
            double width; };

        class Rectangle: public Shape {
        public:   
            Rectangle(double h, double w): Shape(h,w) {};
            double getarea() override { return height*width; }    };

        class Triangle : public Shape {
        public:
                Triangle(double h, double w) :Shape(h,w) {};
                double getarea() { return height*width*0.5; }};

        int main() {
        //create objects
            Rectangle Rec(10, 20);
            Triangle Tri(2, 3);


        //create boost bind function
            boost::function<double(double, double)> g1;
            g1 = boost::bind(boost::mem_fn(&Shape::getarea), Rec);
    //print area and g
            cout << Rec.getarea()<<" should be equal to " << g1<< '\n';


    //create list
            vector<shared_ptr<Shape>> Plist;
            Plist.push_back(make_shared<Rectangle>(Rec));
            Plist.push_back(make_shared<Triangle>(Tri));


        //print each element from the vector list 

        for (auto iter = Plist.begin(); iter != Plist.end(); iter ++ ) {

                boost::function<double(double, double)> g2;

                g2= boost::bind(boost::mem_fn(& ....  , &(**iter));

        //where in dots we need Classtype_of_**iter::getarea 

            cout << (**iter).getarea()<<"should be equal to " << g2<< '\n';

        }


        }

1 个答案:

答案 0 :(得分:0)

你......忘记调用函数......

sonarqube {

    properties {
        properties["sonar.tests"] += sourceSets.integrationTest.allSource.srcDirs.findAll({it.exists()})

        if (file("$project.buildDir/jacoco/test.exec").exists())
            property "sonar.jacoco.reportPath", "$project.buildDir/jacoco/test.exec"
        if (file("$project.buildDir/jacoco/integrationTest.exec").exists())
            property "sonar.jacoco.itReportPath", "$project.buildDir/jacoco/integrationTest.exec"
    }
}

您看到隐含转换为bool(http://www.boost.org/doc/libs/1_60_0/doc/html/boost/function.html#idm45507164686720-bb

的内容

另请注意,我修复了for (auto iter = Plist.begin(); iter != Plist.end(); iter++) { boost::function<double()> g2; g2 = boost::bind(&Shape::getarea, iter->get()); cout << (*iter)->getarea() << " should be equal to " << g2() << '\n'; } g1的签名: Live On Coliru

进一步改进(在循环中不需要g2?):

g2

或者,确实在c ++ 11中:

auto getarea = boost::mem_fn(&Shape::getarea);
for (auto iter = Plist.begin(); iter != Plist.end(); iter++) {
    cout << (*iter)->getarea() << " should be equal to " << getarea(**iter) << '\n';
}

到这个时候,你会想知道为什么你可以使用这个成员来拥有这个访问者。