带有RTTI的C++11元组中的树

Tree in C++11 tuple with RTTI

本文关键字:元组 C++11 RTTI 带有      更新时间:2023-10-16

我想用Python的方式在C++11元组中实现一个简单的树。在Python中,我们可以使用类型(obj)来检查运行时对象的类型,并将不同类型的对象传递给一个函数,我已经为calc()编写了伪代码,如何在c++中做到这一点?

我尝试打印typeid(child1).name()和typeid(tree).name。

我的环境是g++4.8.1。谢谢

// pseudo code
int calc(tuple tree) {
  symbol = type(get<0>(tree));
  l_child = type(get<1>(tree));
  r_child = type(get<2>(tree));
  l = (type(l_child) == tuple) ? calc(l_child) : l_child;
  r = (type(r_child) == tuple) ? calc(r_child) : r_child;
  return l symbol r;
}
int main() 
{
  auto l_child = make_tuple('*', 1, 2);
  auto r_child = make_tuple('-', 5, 1);
  auto tree = make_tuple('+', l_child, r_child);
  cout << calc(tree) << endl;
}

Python和C++是非常不同的语言。C++是静态类型的,Python不是。将Python技术移植到C++可能有效,也可能无效。在这种情况下,它不会起作用。

在Python中,只有一个元组类,可以表示任何元组;在C++中,有无限多的元组类型,每种类型都能够保存特定类型的数据。正如您对typeid的实验所恰当地证明的那样,它们是不可互换的。

在C++中,不能在元组中包含任意树。编写一个树类(或者更好的是,一个类模板)。

编辑:从技术上讲,如果将元组与指针和并集相结合,就可以避开元组。但不建议这样做。你的树将成为你的中心抽象,暴露像指针和联合这样的低级别细节会适得其反,应该避免。C++的方法是编写一个类,并坚持它。

这是不真实的,因为typeid().name的结果是实现定义的。

const char* name() const noexcept;

返回:一个实现定义的ntbs

但是,这里不能使用三元运算符,因为calc(l_child)将在编译时求值,所以如果l_child不是元组,编译将失败。

您可以使用一些类型特征(或重载),因为tuple成员在编译时是已知的。

int calc(int value)
{
    return value;
}
template<typename Left, typename Right>
int calc(const std::tuple<char, Left, Right>& tuple)
{
   char symbol = std::get<0>(tuple);
   Left l_child = std::get<1>(tuple);
   Right r_child = std::get<2>(tuple);
   int l = calc(l_child);
   int r = calc(r_child);
   return l /*symbol*/, r;
}

实例