2

从我的另一个问题,从 std 容器 frm 任意源对象复制,我设法让模板几乎在 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*> >'
4

2 回答 2

1

我认为错误来自第二个声明,这完全是非法的。您正在创建对 non-const 的引用ReadOnlyIterator,因此您不能使用临时(例如由转换构造函数创建的)初始化它。如果您需要参考,请使用对const. 但你可能不需要一个。

第三个声明:

ReadOnlyIterator<SimpleClass *> t2(v) = v;

在语法上是错误的。

于 2013-05-18T17:08:34.953 回答
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:

于 2013-05-18T17:09:00.323 回答