从我在这里的另一个问题Copying from std container frm arbitrary source object我设法让模板几乎在MSVC下运行。不幸的是,编译器崩溃了添加构造函数以接受所有类型的std容器的最新添加,而我的真实项目无论如何都在gcc中。现在当我在gcc中使用这个模板时,我得到了几个我不知道如何解决的错误。
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();
}
};
我的目标是允许这样的作业:
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;
我更新了上面的代码并恢复了我应用的错误更改。所以现在我只得到了我试图解决的原始问题:
ReadOnlyIterator<SimpleClass *> &t1 = v;
导致:
invalid initialization of reference of type 'ReadOnlyIterator<SimpleClass*>&' from expression of type 'std::vector<SimpleClass*, std::allocator<SimpleClass*> >'
答案 0 :(得分:1)
我认为错误来自第二个声明,这完全是非法的。您正在创建对非const ReadOnlyIterator
的引用,因此您无法使用临时(例如,由转换构造函数创建的)初始化它。如果您需要参考,请使用对const
的引用。但你可能不需要一个。
第三项声明:
ReadOnlyIterator<SimpleClass *> t2(v) = v;
在语法上是错误的。
答案 1 :(得分:1)
如您所知,如果您在另一个模板类中编写模板类,则必须为模板参数指定不同的名称:
template <typename U, typename V>
struct is_same<U, V>
{
enum { value = 0 };
};
在is_same
的特化中,在指定专用类名时必须使用相同类型(您也可以将其命名为U
,但使用相同的名称在所有三个地方:在模板参数列表中以及在专门的类名称中:
template <typename V>
struct is_same<V, V>
{
enum { value = 1 };
};
另外,正如评论中所提到的,您应该使用这些辅助类struct
而不是class
;那么你不必写public:
。