问题
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