Does C ++ have a Python equivalent __setitem__

As soon as the title asks if C ++ has a Python equivalent of setitem and getitem for classes?

It basically allows you to do something like the following.

MyClass anObject;

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

      

+2


source to share


5 answers


basically you are overloading the index operator ( operator[]

) and it returns a reference (so it can be read and written)



+6


source


You can overload the [] operator, but this is not exactly the same as a separate getitem / setitem method pair, since you cannot specify any other processing for getting and setting.



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

+6


source


There is an interesting discussion about what is possible (and what is wrong) in C ++ with indexes in this article .

+3


source


To expand the Earwicker log message:

#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 __getitem__.
        operator const Type&() const
        {
            return elem_;
        }

        // Similar to Python __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";
}

      

+1


source


It is not portable, but MSVC has a __ declspec (property) that also allows indexers to:

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

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

      

other than that, Erviker described a portable solution, but he is right that you will have problems.

+1


source







All Articles