微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C ++ Lambda函数指针

如何解决C ++ Lambda函数指针

我有三节课:

dfs

我想在class ShapeEditor {} class PointEditor: ShapeEditor{} class RectEditor: ShapeEditor{} 类中定义一个函数指针,并将其作为lambda函数传递给构造函数。看起来像这样:

Manager

然后我在main中写作

class Manager {
public:
  ShapeEditor (*factory)();
  Manager(ShapeEditor (*_factory)());
}

并收到一条错误消息,指出该表达式没有构造函数

当我在Manager m = Manager([] { return PointEditor(); } 中将ShapeEditor更改为PointEditor时-可以正常工作,但是我需要在函数结果中指定不同的类型。

解决方法

@NathanOliver在以上评论中给出了正确答案:

是的,但是您没有为lambda指定返回类型,因此它是从返回的对象中获取的,并且该对象的类型与函数指针所需的返回类型不同

这是我的解决方法:

Manager m = Manager([] -> ShapeEditor { return PointEditor(); });
,

您的问题是您的lambda返回的类型为ShapeEditor的对象值,该对象值是从ShapeEditor继承的,并且基类值是预期的。

基本上,您期望某种多态性,但是当您期望基本类型的值时,您将返回某些特定子类型的值!这会导致静默转换,结果行为与您期望的不同,因此您的答案不正确。

如果需要多态性,则需要使用指针或引用:

#include <memory>
#include <string>

class ShapeEditor {
public:
    virtual ~ShapeEditor() {}
    virtual std::string doSomething() = 0;
};

class PointEditor: public ShapeEditor {
public:
    std::string doSomething() override;
};

class RectEditor: public ShapeEditor{
public:
    std::string doSomething() override;
};

using ShapeEditorPtr = std::unique_ptr<ShapeEditor>;

class Manager {
public:
  ShapeEditorPtr (*factory)();

  Manager(ShapeEditorPtr (*_factory)());
};

void test() {
    Manager m = Manager([]() -> ShapeEditorPtr { 
        return std::make_unique<PointEditor>();
    });
}

https://godbolt.org/z/xP4czj

,

如我所见,您的问题是尝试将PointEditor实例转换为ShapeEditor实例。您需要转换指针,而不是值。因此,在lambda表达式中,您将返回本地实例PointEditor的COPY,并尝试将其复制到ShapeEditor本地变量中。

这是我的建议:

#include <cmath>
#include <cstdio>
#include <map>
#include <iostream>

using namespace std;

class ShapeEditor {
public:
    virtual void printName(){};
};

class PointEditor: ShapeEditor{
    
public:
    void printName(){cout << "PointEditor\n";};
};

class RectEditor: ShapeEditor{
    
public:
    void printName(){cout << "RectEditor\n";};
};

class Manager {
    ShapeEditor* shp;
    ShapeEditor* (*factory) ();
public:
    Manager( ShapeEditor* (*_factory)() ):factory{_factory}{
        shp = factory();
        shp->printName();
    };
    
    ~Manager(){delete shp;}
};

int main()
{
    
    ShapeEditor* (*func1)() = [](){
        PointEditor* x = new PointEditor();
        ShapeEditor* s = (ShapeEditor*)x;
        return s;
        
    };
    
    ShapeEditor* (*func2)() = [](){
        RectEditor* x = new RectEditor();
        ShapeEditor* s = (ShapeEditor*)x;
        return s;
    };
    
    Manager m1 = Manager(func1);
    Manager m2 = Manager(func2);
    
    return 0;
}

输出:

PointEditor
RectEditor

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。