Reputation: 22074
From my other question here Copying from std container frm arbitrary source object I managed to get the template almost working under MSVC. Unfortunately the compiler crashes with the newest addtion of adding a constructor to accept all kind of std containers, and my real project is in gcc anyway. Now when I use this template in gcc, I get several errors I don't know how to resolve.
template <class T> class ReadOnlyIterator
{
public:
template <typename V, typename U>
struct is_same
{
enum { value = 0 };
};
template <typename V>
struct is_same<V, V>
{
enum { value = 1 };
};
template <bool, typename>
struct enable_if
{};
template <typename V>
struct enable_if<true, V>
{
typedef V type;
};
template <typename Container>
typename enable_if<
is_same<T, typename Container::value_type>::value, ReadOnlyIterator<T>&>::type operator= (const Container &v)
{
return *this;
}
template <typename Container>
ReadOnlyIterator(const Container &v, typename enable_if<is_same<T, typename Container::value_type>::value, void>::type * = 0)
{
mVector = v;
mBegin = mVector.begin();
}
};
My goal was to allow assignments like this:
std::vector<SimpleClass *>v;
std::list<SimpleClass *>l;
ReadOnlyIterator<SimpleClass *> t0 = v;
ReadOnlyIterator<SimpleClass *> &t1 = v;
ReadOnlyIterator<SimpleClass *> t2 = ReadOnlyIterator<SimpleClass *>(v);
ReadOnlyIterator<SimpleClass *> t3 = l;
t0 = v;
t0 = l;
I updated the code above and reverted the wrong changes I applied. So now I only get the original problem I tried to fix:
ReadOnlyIterator<SimpleClass *> &t1 = v;
leads to:
invalid initialization of reference of type 'ReadOnlyIterator<SimpleClass*>&' from expression of type 'std::vector<SimpleClass*, std::allocator<SimpleClass*> >'
Upvotes: 2
Views: 144
Reputation: 45665
As you already found out, if you write a template class within another template class, you have to give the template parameters different names:
template <typename U, typename V>
struct is_same<U, V>
{
enum { value = 0 };
};
In the specialization of is_same
, you have to use the same types when specifying the specialized class name (you can also name it U
, but use the same name on all three places: in the template parameter list as well as in the specialized class name):
template <typename V>
struct is_same<V, V>
{
enum { value = 1 };
};
Also, as mentioned in the comments, you should make these helper-classes struct
instead of class
; then you don't have to write public:
.
Upvotes: 1
Reputation: 171097
I assume the error comes from the second declaration, which is simply illegal. You're creating a reference to non-const ReadOnlyIterator
, so you cannot initialise this with a temporary (such as one created by the converting constructor). If you need a reference, use a reference to const
. But you probably don't need one.
The third declaration:
ReadOnlyIterator<SimpleClass *> t2(v) = v;
is syntactically wrong.
Upvotes: 1