【问题标题】:Get iterator for const reference获取 const 引用的迭代器
【发布时间】:2016-06-25 11:51:40
【问题描述】:

我正在开发一个必须使用begin() 方法返回迭代器的类。此外,我必须开发一个函数来接收此类的 const 引用并对其进行迭代。

当我尝试从此方法获取迭代器时,出现以下编译错误:"the object has type qualifiers that are not compatible with the member function."我不明白为什么会出现此错误。

这是我写的代码:

// ------------ class Neuron -------------
class Neuron { ... };
// ---------------------------------


// ------------ class AbstractLayer -------------
class AbstractLayer {
public:

    class Iterator : public std::iterator<std::input_iterator_tag, Neuron> {
        public:
            Iterator(Neuron *neurons) : _neurons(neurons) {}
        private:
            Neuron *_neurons;
    };

    virtual Iterator begin() = 0;
    virtual const Iterator begin2() = 0;
};
// ----------------------------------------


// ------------ class Layer -------------
class Layer : AbstractLayer {

public:
    Layer(){};
    Iterator begin(){ return Iterator(_neurons); }
    const Iterator begin2(){ return (const Iterator)begin(); }

private:
    Neuron *_neurons;
    int _size;
};
// --------------------------------


// ------------ Method where the problem is -------------------
void method(const AbstractLayer &layer){
    // Error in both methods: 
    // "the object has type qualifiers that are not compatible with the member function."
    layer.begin();
    layer.begin2();
}
// -------------------------------------------------------------

【问题讨论】:

    标签: c++ stl


    【解决方案1】:

    method 函数中,layer 引用了一个常量 对象。这意味着您只能调用标记为const 的函数。比如

    class AbstractLayer {
    public:
        ...
        virtual const Iterator begin() const = 0;  // <- Note use of `const` here
        ...
    };
    

    【讨论】:

      【解决方案2】:

      您不需要beginbegin2。你需要的是begin 的两个版本——常量和非常量。一个 const 将返回 const 迭代器。您可能还需要一个始终返回 const 迭代器的 cbegin(仅限 const)。

      【讨论】:

        【解决方案3】:

        method 中,layer 参数是 const,它会阻止您在其上调用非常量方法。如果您通过非常量引用 (void method(AbstractLayer &amp;layer)) 获取层,您将能够调用这两种方法。

        您可能应该提供一个返回 const_iterator 的 const begin 方法,以便您可以迭代 const AbstractLayer

        【讨论】:

          【解决方案4】:

          您的函数接受const AbstractLayer,这意味着只能在其上调用const 成员函数。但是,beginbegin2 不是 const。事实上,鉴于只有begin2 返回一个const Iterator,因此无论如何尝试在此方法中调用begin 是没有意义的。

          改变

          virtual const Iterator begin2() = 0;
          

          virtual const Iterator begin2() const = 0;
          

          const Iterator begin2()
          

          const Iterator begin2() const
          

          最后,返回 const Iterator 在您的代码中实际上是没有意义的,因为 const 由于返回了右值而被丢弃。无论如何,当您调用begin 时,您不需要强制转换为const Iterator;只需返回一个Iterator,编译器就会注意将其设为常量。

          最后,您的Layer 类需要公开派生自AbstractLayer

          class Layer : public AbstractLayer
          

          Live Demo

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-09-13
            • 1970-01-01
            • 2016-11-26
            • 1970-01-01
            • 2016-09-03
            • 1970-01-01
            相关资源
            最近更新 更多