简体   繁体   中英

Overload [] subscript operator for std::any

is there any way to overload the operator[] for std::any?

I have a struct looking like this:

struct Container {
public:
  template <typename T>
  void push_back(const T &t) { 
    m_container.push_back(t);
  }
private:
  std::vector<std::any> m_container;
}

Now I'd like to be able to access an element by index (which can be of any type).

I think of a visitor like

struct subscript_visitor {
 std::string operator[](const size_t &idx) {

 }

 int operator[](const size_t &idx) {

 }
 
 ...
}

But functions with the same return type reasonably cannot be declared.

Any idea how to solve this so that something like

Container c; 
c.push_back(0);
std::cout << c[0];

Will work?

You need to store additional info, if you want to access the type later. You could do so by storing a function pointer to a specialization of a template function used for printing. You'll need to add one data member to the vector element per function you want to access though to make this work. std::variant may be preferrable in this scenario depending on the use case.

struct Container {
public:
    template <typename T>
    void push_back(T&& t) {
        m_container.emplace_back(std::forward<T>(t));
    }

    struct Element
    {
        template<class U>
        Element(U&& value)
            : m_value(std::forward<U>(value)),
            m_printFunction(&Container::Print<U>)
        {
        }

        std::any m_value;
        void (*m_printFunction)(std::ostream&, std::any const&);
    };

    Element const& operator[](size_t index) const
    {
        return m_container[index];
    }

private:

    template<class U>
    static void Print(std::ostream& s, std::any const& value)
    {
        s << any_cast<U>(value);
    }

    std::vector<Element> m_container;
};


std::ostream& operator<<(std::ostream& s, Container::Element const& value)
{
    value.m_printFunction(s, value.m_value);
    return s;
}

int main()
{
    Container c;
    c.push_back(0);
    c.push_back(std::string("Hello World"));

    std::cout
        << c[0] << '\n'
        << c[1] << '\n';
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM