C++ Boost

Boost.Python

Frequently Asked Questions (FAQs)


Is return_internal reference efficient?
How can I wrap containers which take C++ containers as arguments?

Is return_internal reference efficient?

質問: 12 個の double からなるオブジェクトがある。このオブジェクトへの const& 付き参照が、他のクラスのメンバ関数によって返される。 戻り値オブジェクトの使用に関して、Python の観点では、 戻り値がコピーか参照かなどは気にしない。 Boost.Python Version 2 では copy_const_referencereturn_internal_reference の選択がある。 生成コードサイズやメモリのオーバヘッドのようなことで、 一方より他方が良いとする考えはあるか?

解答: copy_const_reference は、メモリ上にオブジェクトの実体を作成する。そのサイズは size = base_size + 12 * sizeof(double) である。return_internal_reference は、メモリ上にオブジェクトのポインタを作成する。そのサイズは size = base_size + sizeof(void*) である。 しかし、それは弱いオブジェクト参照を生み出す。ソースオブジェクトの弱い参照リストに含まれ、 内部参照オブジェクトの生存期間を管理すべき、特別なコールバックオブジェクトになる。 私見かもしれないが、この場合 copy_const_reference の方を薦める。 その結果、全体のメモリ使用量と断片化が減り、たぶんトータル回数も減る。

How can I wrap functions which take C++ containers as arguments?

Ralf W. Grosse-Kunstleve はこのノートを明らかにしている。

  1. 標準 class_<> ラッパの使用方法。
    class_<std::vector<double> >("std_vector_double")
      .def(...)
      ...
      ;
    
    これはテンプレートに変更可能なので、いくつかの型 (double, int, long, etc.) は同じコードでラップできる。このテクニックは "scitbx" パッケージの中にある次のファイルで使用されている。
    scitbx/include/scitbx/array_family/boost_python/flex_wrapper.h
    このファイルの std::vector<> をラップしてすげかえる修正は簡単にできる。

    この手の C++/Python 連結は、沢山 (10000 以上) の要素を含むコンテナに最適だ。

  2. カスタム右辺値コンバータ (custom rvalue converters) の使用方法。 Boost.Python "rvalue converters" は関数記述を次のように合わせる。
    void foo(std::vector<double> const& array); // pass by const-reference
    void foo(std::vector<double> array); // pass by value
    
    カスタム右辺値コンバータは、次のファイルに実装されている。
    scitbx/include/scitbx/boost_python/container_conversions.h
    このコードは、たとえば C++ コンテナタイプ std::vector<> や std::list<> から、Python のタプル (tuples) への変換に使用でき、その逆も可能である。 いくつかの単純な例が、このファイルの中にある。
    scitbx/array_family/boost_python/regression_test_module.cpp
    C++ コンテナと Python タプルの自動交換は、適度なサイズのコンテナに最適だ。 これらのコンバータは、前者と比べて意味のないコードを生成する。
後者を使用して不利なことは、+,-,*,/,% のような算術演算子が使えないことである。 仮にタプルの代わりに数値配列 "math_array" に変換するカスタム右辺値コンバータがあれば便利になるだろう。 これは現在実装されていないが、あと2週間もあればリリースされる Boost.Python V2 のフレームワークでは可能になる。 [この記事は 2002/03/10 に投稿された]

たとえば std::vector<> < と Python リストの交換もできる カスタム右辺値コンバータが可能なら、これも便利だ。 例題のように、このコンバータは C++ から Python リストの編修をサポートするだろう。

C++:

void foo(std::vector<double>& array)
{
  for(std::size_t i=0;i<array.size();i++) {
    array[i] *= 2;
  }
}
Python:
>>> l = [1, 2, 3]
>>> foo(l)
>>> print l
[2, 4, 6]
カスタム右辺値コンバータは Boost.Python コアライブラリの変更を必要とする。 そして現在は利用できない。

P.S.:

上記 "scitbx" ファイルは、匿名 CVS を利用して参照できる。

cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx login
cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx co scitbx

Revised 05 November, 2002

© Copyright Dave Abrahams 2002. All Rights Reserved.