1

C++11 のタプルに Python 流の単純なツリーを実装したいと考えています。Python では、type(obj) を使用してランタイム オブジェクト タイプをチェックし、異なるタイプのオブジェクトを 1 つの関数に渡すことができます。

typeid(child1).name() と typeid(tree).name() を出力しようとしましたが、それらは 'St5tupleIIciiEE' と 'St5tupleIIcS_IIciiEES0_EE' です。

私の環境は 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;

}
4

2 に答える 2

2

Python と C++ は非常に異なる言語です。C++ は静的に型付けされますが、Python はそうではありません。Python の手法を C++ に移植しても、うまくいく場合とうまくいかない場合があります。この場合、うまくいきません。

Python では、任意のタプルを表すことができるタプル クラスは 1 つだけです。C++ には無数のタプル型があり、それぞれが特定の種類のデータを保持できます。typeidあなたの実験が適切に示しているように、それらは交換可能ではありません。

C++ では、任意のツリーをタプルに保持することはできません。ツリー クラス (またはクラス テンプレート) を記述します。

編集: 技術的には、タプルをポインターおよび共用体と組み合わせると、タプルを回避できます。ただし、これは推奨されません。ツリーが中心的な抽象化になるため、ポインターや共用体などの低レベルの詳細を公開することは非生産的であり、避ける必要があります。C++ の方法は、クラスを作成することです。それに固執します。

于 2013-06-24T07:26:25.090 に答える
1

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;
}

実際の例

于 2013-06-24T07:11:44.190 に答える