Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
388 views
in Technique[技术] by (71.8m points)

c++ - Copying from std container frm arbitrary source object

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> &'
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...