Class Operators/Special Functions

Python Operators

C は豊富な演算子で知られている。C++ は演算子のオーバロードを可能にし、これを究極まで拡張した。 Boost.Python はこの利点を生かすと同時に、拡張演算子を持つ C++ クラスのラップを簡素化した。

ファイル位置クラス FilePos と、そのインスタンスをあつかう演算子について考える。

    class FilePos { /*...*/ };

    FilePos     operator+(FilePos, int);
    FilePos     operator+(int, FilePos);
    int         operator-(FilePos, FilePos);
    FilePos     operator-(FilePos, int);
    FilePos&    operator+=(FilePos&, int);
    FilePos&    operator-=(FilePos&, int);
    bool        operator<(FilePos, FilePos);

クラスと種々の演算子を Python にマップすることは非常に容易であり、直感的でもある。

    class_<FilePos>("FilePos")
        .def(self + int())          // __add__
        .def(int() + self)          // __radd__
        .def(self - self)           // __sub__
        .def(self - int())          // __rsub__
        .def(self += int())         // __iadd__
        .def(self -= other<int>())
        .def(self < self);          // __lt__

上記のコード片はとても明白でほとんど説明の必要がない。演算子の記名は実際同じである。 少しだけ注意すべきことは self が FilePos オブジェクトへの参照であることだ。 またすべてのクラスではないが、演算子がある式に関係付けたい場合、 (安易に)デフォルトコンストラクト可能でもある。"self" 式が書いてある場合、 現実のインスタンス T の代わりに other<T>() を使用できる。

Special Methods

Python にはもう少し特別メソッド (Special Methods) が存在する。 Python クラスインスタンスによりサポートされる標準の特別メソッド名に関して Boost.Python はすべてサポートする。 直感的なインタフェースをもつ等価品は C++ 関数をラップするのに使われる。 それらは Python の特別メソッドに一致する。例題をあげる。

    class Rational
    { operator double() const; };

    Rational pow(Rational, Rational);
    Rational abs(Rational);
    ostream& operator<<(ostream&,Rational);

    class_<Rational>()
        .def(float_(self))                  // __float__
        .def(pow(self, other<Rational>))    // __pow__
        .def(abs(self))                     // __abs__
        .def(str(self))                     // __str__
        ;

これで十分だろう。

What is the business of operator<< .def(str(self))? Well, the method str requires the operator<< to do its work (i.e. operator<< is used by the method defined by def(str(self)).