Copying from std container frm arbitrary source object

旧时模样 提交于 2019-12-11 14:56:24

问题


I created a read only iterator which allows me to use it in a for loop more conveniently then with the std iterators, similar to what boost does with the FOREACH (not as good but good enough :))

Now it looks like this:

for(ReadOnylIterator<MyClass *> class = parent.getIterator(); class.end(); ++class)
   class->function();

The problem that I have now is, that I must implement a function on the parent which returns the iterator. Since the std containers have all the same syntax, I was wondering if it is possible to define a copy constructor/assignment operator on the Iterator that accepts any of the std:: containers and creates the copy itself, instead of requiring the class to return it.

Of course I want to avoid having to define all of them myself like as there are lots of them:

ReadOnlyIterator<T> &operator=(std::list<T> const &v)
ReadOnlyIterator<T> &operator=(std::vector<T> const &v)
...

Is there a way to do this? When I look at the source of the vector I don't see a common base class, so I think it might not be posssible.

I don't understnad why the assignment operator doesn't work.

In my code I test it like this:

std::vector<SimpleClass *>t;
ReadOnlyIterator<SimpleClass *> &it = t;

And I get

error C2440: 'initializing' : cannot convert from 'std::vector<_Ty>' to 'ReadOnlyIterator<T> &'

回答1:


If I understand you correctly, this should work:

#include <type_traits>

template <typename Container>
typename std::enable_if<std::is_same<T, typename Container::value_type>::value, ReadOnlyIterator<T>&>::type operator= (const Container &v);

The above code uses C++11. If you don't have access to that, you could use the equivalent functionality from Boost.

Live example


In case you can use neither C++11 nor Boost, you can code the necessary classes yourself:

template <typename T, typename U>
struct is_same
{
    enum { value = 0 };
};

template <typename T>
struct is_same<T, T>
{
    enum { value = 1 };
};

template <bool, typename>
struct enable_if
{};

template <typename T>
struct enable_if<true, T>
{
    typedef T type;
};

To use this in a constructor, define it like this:

template <typename Container>
ReadOnlyIterator(const Container &v, typename enable_if<is_same<T, typename Container::value_type>::value, void>::type * = 0) {}

Live example




回答2:


I'm sorry but no, this is not possible given that the containers don't have common base classes. You'll have to write an operator for each container, Sad news !

Although if the behavior of the operator functions is always the same, you could just make a macro that contains the code, and copy paste it for every container type ^_^



来源:https://stackoverflow.com/questions/16622398/copying-from-std-container-frm-arbitrary-source-object

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!