Scott
Scott

Reputation: 5263

Does C++ have an equivilent to Python's __setitem__

Just as the title asks, does C++ have the equivalent of Python's setitem and getitem for classes?

Basically it allows you to do something like the following.

MyClass anObject;

anObject[0] = 1;
anObject[1] = "foo";

Upvotes: 2

Views: 1252

Answers (4)

peterchen
peterchen

Reputation: 41106

It's not portable, but MSVC has __declspec(property), which also allows indexers:

struct Foo
{
   void SetFoo(int index, int value) { ... }
   int GetFoo(int index) { ... }

   __declspec(property(propget=GetFoo, propput=SetFoo)) int Foo[]; 
}

other than that, Earwicker did outline the portable solution, but he's right that you'll run into many problems.

Upvotes: 1

dalle
dalle

Reputation: 18517

To expand on Earwicker post:

#include <string>
#include <iostream>

template <typename Type>
class Vector
{
public:
    template <typename Element>
    class ReferenceWrapper
    {
    public:
        explicit ReferenceWrapper(Element& elem)
         : elem_(elem)
        {
        }

        // Similar to Python's __getitem__.
        operator const Type&() const
        {
            return elem_;
        }

        // Similar to Python's __setitem__.
        ReferenceWrapper& operator=(const Type& rhs)
        {
            elem_ = rhs;
            return *this;
        }

        // Helper when Type is defined in another namespace.
        friend std::ostream& operator<<(std::ostream& os, const ReferenceWrapper& rhs)
        {
            return os << rhs.operator const Type&();
        }

    private:
        Element& elem_;
    };

    explicit Vector(size_t sz)
     : vec_(sz)
    {
    }

    ReferenceWrapper<const Type> operator[](size_t ix) const
    {
        return ReferenceWrapper<const Type>(vec_[ix]);
    }

    ReferenceWrapper<Type> operator[](size_t ix)
    {
        return ReferenceWrapper<Type>(vec_[ix]);
    }

private:
    std::vector<Type> vec_;
};

int main()
{
    Vector<std::string> v(10);
    std::cout << v[5] << "\n";

    v[5] = "42";
    std::cout << v[5] << "\n";
}

Upvotes: 2

Daniel Earwicker
Daniel Earwicker

Reputation: 116714

You can overload the [] operator, but it's not quite the same as a separate getitem/setitem method pair, in that you don't get to specify different handling for getting and setting.

But you can get close by returning a temporary object that overrides the assignment operator.

Upvotes: 6

newacct
newacct

Reputation: 122489

basically, you overload the subscript operator (operator[]), and it returns a reference (so it can be read as well as written to)

Upvotes: 7

Related Questions