使用lambda函数修改类

时间:2019-06-04 01:05:54

标签: c++ class lambda

我目前正在尝试在包含指向名为std::transform()的类的智能指针的向量上使用Triangle,在该向量中,我有几种更改Triangle参数的方法。

现在,我想让生活更轻松,将std::transform()与我自己的lambda函数一起使用,并将其应用于每个动态分配的三角形。

但是,当我尝试在该lambda函数中访问类的私有属性时遇到问题。 我很好奇如何解决这个问题?

typedef std::pair<double, double> Point;

//the class Triangle contains these methods:

class Triangle{
    Point t1, t2, t3;
public:
    Trougao(const Point &t1, const Point &t2, const Point &t3){
        if(Triangle::Orijentacija(t1,t2,t3)==0) 
            throw std::domain_error("Incorrect vertices");
        Triangle::t1.first=t1.first;
        Triangle::t1.second=t1.second;
        Triangle::t2.first=t2.first;
        Triangle::t2.second=t2.second;
        Triangle::t3.first=t3.first;
        Triangle::t3.second=t3.second;
    }

    void Set(const Point &t1, const Point &t2, const Point &t3){
        if(Triangle::Orientation(t1,t2,t3)==0)
            throw std::domain_error("Incorrect vertices");
        Triangle::t1.first=t1.first;
        Triangle::t1.second=t1.second;
        Triangle::t2.first=t2.first;
        Triangle::t2.second=t2.second;
        Triangle::t3.first=t3.first;
        Triangle::t3.second=t3.second;
    }

    void Set(int indeks, const Point &t){
        if(indeks!=1 && indeks!=2 && indeks!=3)
            throw std::range_error("Incorrect index");
        if(indeks==1){
            this->t1.first=t.first;
            this->t1.second=t.second;
        }
        else if(indeks==2){
            this->t2.first=t.first;
            this->t2.second=t.second;
        }
        else if (indeks==3){
            this->t3.first=t.first;
            this->t3.second=t.second;
        }
    }

    Point GiveVertex(int indeks) const{
        if(indeks!=1 && indeks!=2 && indeks!=3)
            throw std::range_error("Incorrect index");
        if(indeks==1) return Triangle::t1;
        else if(indeks==2) return Triangle::t2;
        else if(indeks==3) return Triangle::t3;
    }

    void Translate(double delta_x, double delta_y){
        t1.first+=delta_x;
        t1.second+=delta_y;
        t2.first+=delta_x;
        t2.second+=delta_y;
        t3.first+=delta_x;
        t3.second+=delta_y;
    }
};

//now I would like to make in my main program a vector of smart pointers 
//which I would use do dyn. alloc. "n" Triangles. After that I want to use 
//std::transform to Translate every single one (with lambda function)
//I am currently stuck at implementation of this lambda function as you can 
// see:
//-------------(main)------------------------------
int main()
{
    std::cout<<"How many triangles: ";
    std::cin>>n;
    std::vector<double> translation_vector(2);
    double angle, scale_faktor;
    Point dot1, dot2, dot3; 
    std::vector<std::shared_ptr<Triangle>> vect_smrt_ptr(n);
    for(int i(0); i<n; i++){
        std::cout<<"Input data for the"<<i+1<<". triangle (x1 y1 x2 y2 x3 y3):";
        std::cin>>dot1.first>>dot1.second>>dot2.first>>dot2.second>>dot3.first>>dot3.second;
        std::shared_ptr<Triangle> smrt_ptr(new Triangle(dot1, dot2, dot3));
        vect_smrt_ptr.at(i)=smrt_ptr;
    }
    std::cout<<"Input translation vector (dx dy): ";
    std::cin>>translation_vector.at(0)>>translation_vector.at(1);

    //now the tricky part!
    std::transform(&vect_smrt_ptr.at(0), &vect_smrt_ptr.at(vect_smrt_ptr.size()), &vect_smrt_ptr.at(0),
        [translation_vector](Triangle tr){ tr.Translate(translation_vector.at(0), translation_vector.at(1)); }
    );

1 个答案:

答案 0 :(得分:0)

std::transform在您的情况下不是一个很好的选择,因为它应该将一个对象集合转换为另一个集合(当然,在特定情况下,输出集合可以与输入集合相同)。像这样:

std::transform(inputCollection.begin(), inputCollection.end(), outputCollection.begin(),
    [](YourClass obj) {
        YourClass modified = ApllySomeModification(obj);
        return modified;
    });

在您的情况下,std::for_each是更好的算法:

std::for_each(vect_smrt_ptr.begin(), vect_smrt_ptr.end(),
    [translation_vector](std::shared_ptr<Triangle> tr) {
        tr->Translate(translation_vector.at(0), translation_vector.at(1));
    });

因为它具有就地修改元素的语义。