加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – STL const_iterator cast – 编译器差异

发布时间:2020-12-16 09:53:24 所属栏目:百科 来源:网络整理
导读:我正在将一大块代码从 gcc移植到Visual Studio 2013.以下代码示例在gcc 4.4上工作正常(!),但编译begin()和end()在VS2013上失败: error C2440: ” : cannot convert from ‘unsigned char *’ to ‘std::_Vector_const_iterator’ class foo { unsigned cha
我正在将一大块代码从 gcc移植到Visual Studio 2013.以下代码示例在gcc 4.4上工作正常(!),但编译begin()和end()在VS2013上失败:

error C2440: ” : cannot convert from ‘unsigned char *’ to ‘std::_Vector_const_iterator>>’

class foo {
    unsigned char* value;
    int length;

    std::vector<unsigned char>::const_iterator begin();
    std::vector<unsigned char>::const_iterator end();
};

std::vector<unsigned char>::const_iterator foo::begin() {
    return std::vector<unsigned char>::const_iterator(value);
}

std::vector<unsigned char>::const_iterator foo::end() {
    return std::vector<unsigned char>::const_iterator(value + length);
}

鉴于我不想重写整个事物,是否有可行的方法来创建这些const_iterators?

解决方法

没有可移植的方法来执行您正在尝试的操作,因为不需要(const_)迭代器可以从指向底层值类型的指针构造. libstdc碰巧提供了这样的构造函数,但VS标准库实现却没有.相反,它的(const_)迭代器构造函数接受一个指向底层值类型的指针和一个指向容器本身的指针,它用于在调试版本中执行其他验证.

最简单的解决方案是用unsigned char const *替换std :: vector< unsigned char> :: const_iterator.原始指针属于RandomAccessIterator类别,与vector ::(const_)迭代器相同.

unsigned char const *foo::begin() {
    return value;
}

unsigned char const *foo::end() {
    return value + length;
}

如果您需要将迭代器作为类类型,那么您将需要创建自定义迭代器.虽然这可以从头开始,但使用Boost.IteratorFacade要容易得多,这将提供构建自定义迭代器的一堆必要的样板.

#include <boost/iterator/iterator_facade.hpp>

struct const_foo_iterator : boost::iterator_facade<const_foo_iterator,unsigned char const,boost::random_access_traversal_tag>
{
  const_foo_iterator() = default;
  const_foo_iterator(unsigned char const *iter) : iter(iter) {}
private:
    friend class boost::iterator_core_access;

    void increment() { ++iter; }
    void decrement() { --iter; }
    void advance(std::ptrdiff_t n) { iter += n; }

    std::ptrdiff_t distance_to(const_foo_iterator const& other) const
    { return iter - other.iter; }

    bool equal(const_foo_iterator const& other) const
    { return this->iter == other.iter; }

    unsigned char const& dereference() const { return *iter; }
    unsigned char const* iter = nullptr;
};

const_foo_iterator foo::begin() {
    return value;
}

const_foo_iterator foo::end() {
    return value + length;
}

static_assert(std::is_same<std::iterator_traits<const_foo_iterator>::value_type,unsigned char>::value,"value_type");
static_assert(std::is_same<std::iterator_traits<const_foo_iterator>::pointer,unsigned char const *>::value,"pointer");
static_assert(std::is_same<std::iterator_traits<const_foo_iterator>::iterator_category,std::random_access_iterator_tag>::value,"iterator_category");

Live demo

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读