【问题标题】:C++: Forward iterator interface of a member container to class interfaceC ++:将成员容器的迭代器接口转发到类接口
【发布时间】:2017-11-17 11:44:23
【问题描述】:

我正在处理一个具有std::array<double, 2> 数据成员的类,我正在尝试通过简单地将所有内容传递给std::arraybegin()end() 就足够了)为我的类实现一些基本的迭代器机制暂时)。

我正在使用decltypestd::declval 来推断std::arraybegin() 的返回类型。

class myCont {
    public:
    myCont() : data({{-1, 1}}) {}

    /* Pass to iterator mechanism of std::array */
    auto begin() -> decltype(declval<array<double, 2>>().begin()){return data.begin();}
    auto cbegin() -> decltype(declval<array<double, 2>>().cbegin()){return data.cbegin();}
    auto end() -> decltype(declval<array<double, 2>>().end()){return data.end();}
    auto cend() -> decltype(declval<array<double, 2>>().cend()){return data.cend();}

    private:
    array<double, 2> data;
};

使用myCont 作为 const ref 参数会产生关于 const 正确性的错误:将 'const myCont' 作为 'this' 参数传递会丢弃限定符

void myContainerFunc(const myCont& c){
    for(auto it = c.cbegin(); it != c.cend(); it++) // Error
        cout << *it << ' ' << endl;
}   

虽然采用 std::array 的完全相同的函数可以正常工作。

void myContainerFunc(const myCont& c){
    for(auto it = c.cbegin(); it != c.cend(); it++) // works perfectly fine
        cout << *it << ' ' << endl;
}   

为什么myCont::begin() 等的行为不像std::array 的实现,它们应该调用它们?有人可以向我指出我的错误吗? decltype 会抛弃 constness 或类似的东西吗?

谢谢。

【问题讨论】:

  • 您忘记将const 添加到cbegincend 声明中。
  • 确实,谢谢。
  • 此外,容器通常同时具有iterator begin();const_iterator begin() const;,因此当容器被常量访问时,普通的begin 会做“正确的事情”。 end 也一样。

标签: c++ iterator constants decltype


【解决方案1】:

您的方法 cbegin()cend() 应该是 const 限定的:

auto cbegin() const -> decltype(declval<array<double, 2>>().cbegin()) {return data.cbegin();}

如果您检查std::array,您会注意到相应的方法是 const 限定的。

【讨论】:

    猜你喜欢
    • 2012-11-07
    • 2014-08-13
    • 2019-06-06
    • 2013-02-28
    • 2014-02-02
    • 2014-03-31
    • 1970-01-01
    • 2011-05-22
    • 1970-01-01
    相关资源
    最近更新 更多