【问题标题】:Copying from std container frm arbitrary source object从 std 容器从任意源对象复制
【发布时间】:2013-05-18 08:55:37
【问题描述】:

我创建了一个只读迭代器,它允许我在 for 循环中使用它,然后使用 std 迭代器更方便,类似于 boost 对 FOREACH 所做的(不是那么好但足够好:))

现在看起来像这样:

for(ReadOnylIterator<MyClass *> class = parent.getIterator(); class.end(); ++class)
   class->function();

我现在遇到的问题是,我必须在返回迭代器的父级上实现一个函数。由于 std 容器具有相同的语法,我想知道是否可以在 Iterator 上定义一个复制构造函数/赋值运算符,它接受任何 std:: 容器并自行创建副本,而不是要求类返回它。

当然,我想避免自己定义所有这些,因为它们有很多:

ReadOnlyIterator<T> &operator=(std::list<T> const &v)
ReadOnlyIterator<T> &operator=(std::vector<T> const &v)
...

有没有办法做到这一点?当我查看向量的来源时,我没有看到一个通用的基类,所以我认为这可能是不可能的。

我不明白为什么赋值运算符不起作用。

在我的代码中,我这样测试它:

std::vector<SimpleClass *>t;
ReadOnlyIterator<SimpleClass *> &it = t;

我得到了

error C2440: 'initializing' : cannot convert from 'std::vector<_Ty>' to 'ReadOnlyIterator<T> &'

【问题讨论】:

    标签: c++ containers std


    【解决方案1】:

    如果我理解正确,这应该可以:

    #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);
    

    以上代码使用C++11。如果您无权访问它,则可以使用 Boost 的等效功能。

    Live example


    如果你既不能使用 C++11 也不能使用 Boost,你可以自己编写必要的类:

    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;
    };
    

    要在构造函数中使用 this,请像这样定义它:

    template <typename Container>
    ReadOnlyIterator(const Container &v, typename enable_if<is_same<T, typename Container::value_type>::value, void>::type * = 0) {}
    

    Live example

    【讨论】:

    • 我没有可用的 C11,也无法使用 boost。 :(
    • @Devolus 好吧,您可以随时查看 Boost(或只是 google SFINAE)并自己编写相关部分。
    • 感谢您的帮助,但我对这个模板内容的理解非常有限,我不想承认。我将您的更改添加到我的代码中,但我仍然收到错误消息。我更新了我的问题并添加了我得到的错误。不知何故,这个赋值运算符不起作用,我不明白为什么。我也不确定如何使用你给我的这个 Container 类型。我试图让它至少在容器上工作,但即使这样也行不通。
    • 我刚刚注意到你的这个活生生的例子,现在它可以工作了。 :) 谢谢!
    • @Devolus 注意ReadOnlyInterator&lt;T&gt; i = whatever; 不是赋值,它是初始化,,所以它调用构造函数,不是operator=。您也必须为构造函数做同样的事情。没有返回类型,因此您必须在参数中使用enable_if(带有默认参数)。
    【解决方案2】:

    很抱歉,不,这是不可能的,因为容器没有通用的基类。您必须为每个容器编写一个运算符,可悲的消息!

    虽然如果操作符函数的行为总是相同的,你可以只创建一个包含代码的宏,然后为每个容器类型复制粘贴它^_^

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-08
      • 2016-07-22
      • 2014-07-26
      • 1970-01-01
      • 2013-05-13
      相关资源
      最近更新 更多