链接错误 - 功能二叉树,派生类

时间:2014-01-26 15:21:34

标签: c++ class lambda

我想实现一个简单的二叉树,其中顶点包含lambda。

class Element {
public:
    Element() { }
    virtual int operator()();
};

class Node : public Element {
private:
    std::function<int(Element, Element)> fn;
    Element left;
    Element right;
public:
    Node(std::function<int(Element, Element)> _fn, Element _left, Element _right)
        : fn(_fn), left(_left), right(_right) { }
    int operator()() { return fn(left, right); }
};

class Leaf : public Element {
private:
    int value;
public:
    Leaf(int _value) : value(_value) { }
    int operator()() { return value; }
};

int main() {
cout << Node([](Element a, Element b) { return a() + b(); }, Leaf(2), Leaf(5))() << endl;
return 0;
}

以下是我得到的错误:

g++ -Wall -std=c++11 -Wextra -pedantic tree.cc -c
g++ -Wall -std=c++11 -Wextra -pedantic tree.o -o tree
tree.o: In function `main::{lambda(Element, Element)#1}::operator()(Element, Element) const':
tree.cc:(.text+0x18): undefined reference to `vtable for Element'
tree.cc:(.text+0x2a): undefined reference to `vtable for Element'
tree.o: In function `Element::Element()':
tree.cc:(.text._ZN7ElementC2Ev[_ZN7ElementC5Ev]+0xf): undefined reference to `vtable for Element'
tree.o: In function `Element::Element(Element const&)':
tree.cc:(.text._ZN7ElementC2ERKS_[_ZN7ElementC5ERKS_]+0x13): undefined reference to `vtable for Element'
tree.o: In function `Node::Node(std::function<int (Element, Element)>, Element, Element)':
tree.cc:(.text._ZN4NodeC2ESt8functionIFi7ElementS1_EES1_S1_[_ZN4NodeC5ESt8functionIFi7ElementS1_EES1_S1_]+0x4e): undefined reference to `vtable for Element'
tree.o:tree.cc:(.text._ZN4NodeC2ESt8functionIFi7ElementS1_EES1_S1_[_ZN4NodeC5ESt8functionIFi7ElementS1_EES1_S1_]+0x5a): more undefined references to `vtable for Element' follow
tree.o:(.rodata._ZTI4Leaf[_ZTI4Leaf]+0x10): undefined reference to `typeinfo for Element'
tree.o:(.rodata._ZTI4Node[_ZTI4Node]+0x10): undefined reference to `typeinfo for Element'
collect2: error: ld returned 1 exit status
make: *** [tree] Error 1

这是什么意思,是否存在类声明的问题,或者我不理解C ++中函数式编程的某些方面?

2 个答案:

答案 0 :(得分:1)

您尝试使用多态但没有指针/引用。这不起作用:Why doesn't polymorphism work without pointers/references?

有效

Element left;
Element right;

始终为Element类型(不是派生类型),您尝试在其上调用operator()。但是这个方法没有为Element实现,这是错误消息告诉你的。

答案 1 :(得分:1)

您收到链接错误,因为您的基类Element缺少函数调用virtual int operator()();运算符重载函数的实现。

您设计的其他问题

  1. 对基类的所有引用都应该是const引用的'/ Element / const元素&amp; /'
  2. 元素应该是ABC。函数调用重载应该是纯虚拟的。
  3. 函数调用重载应为const类型。
  4. 修改后的程序

    #include <iostream>
    #include <functional>
    using namespace std;
    class Element {
    public:
        Element() { }
        virtual int operator()() const = 0;
    };
    
    class Node : public Element {
    private:
        std::function<int(const Element&,const Element&)> fn;
        const Element& left;
        const Element& right;
    public:
        Node(std::function<int(const Element&, const Element&)> _fn, const Element& _left, const Element& _right)
            : fn(_fn), left(_left), right(_right) { }
        int operator()() const { return fn(left, right); }
    };
    
    class Leaf : public Element {
    private:
        int value;
    public:
        Leaf(int _value) : value(_value) { }
        int operator()() const { return value; }
    };
    
    int main() {
        cout << Node([](const Element& a,const Element& b) { return a() + b(); }, Leaf(2), Leaf(5))() << endl;
        return 0;
    }