我想实现一个简单的二叉树,其中顶点包含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 ++中函数式编程的某些方面?
答案 0 :(得分:1)
您尝试使用多态但没有指针/引用。这不起作用:Why doesn't polymorphism work without pointers/references?
有效
Element left;
Element right;
始终为Element
类型(不是派生类型),您尝试在其上调用operator()
。但是这个方法没有为Element
实现,这是错误消息告诉你的。
答案 1 :(得分:1)
您收到链接错误,因为您的基类Element
缺少函数调用virtual int operator()();
运算符重载函数的实现。
您设计的其他问题
修改后的程序
#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;
}