Class Operators/Special Functions

| Class Operators/Special Functions

## Python Operators

C is well known for the abundance of operators. C++ extends this to the extremes by allowing operator overloading. Boost.Python takes advantage of this and makes it easy to wrap C++ operator-powered classes.

Consider a file position class `FilePos` and a set of operators that take on FilePos instances:

`

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

`

The class and the various operators can be mapped to Python rather easily and intuitively:

`

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

`

The code snippet above is very clear and needs almost no explanation at all. It is virtually the same as the operators' signatures. Just take note that `self` refers to FilePos object. Also, not every class `T` that you might need to interact with in an operator expression is (cheaply) default-constructible. You can use `other<T>()` in place of an actual `T` instance when writing "self expressions".

## Special Methods

Python has a few more Special Methods. Boost.Python supports all of the standard special method names supported by real Python class instances. A similar set of intuitive interfaces can also be used to wrap C++ functions that correspond to these Python special functions. Example:

`

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

`

Need we say more?

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)).

Copyright © 2002-2003 David Abrahams
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.