簡體   English   中英

Visual Studio中的std :: begin和std :: end迭代器

[英]std::begin and std::end iterators in Visual Studio

我正在嘗試在Windows中編譯nghttp2,opensource。 我已經在Linux中成功編譯了相同的文件。

我面臨以下代碼的編譯錯誤。 *

template <size_t N> struct Memchunk {
public:
  Memchunk(Memchunk *next_chunk)
      : pos(std::begin(buf)), last(pos), knext(next_chunk), next(nullptr) {}
  size_t len() const { return last - pos; }
  size_t left() const { return std::end(buf) - (const size_t) last; }
  void reset() { pos = last = std::begin(buf); }
  std::array<uint8_t, N> buf;
  uint8_t *pos, *last;
  Memchunk *knext;
  Memchunk *next;
  static const size_t size = N;
};

*

我收到以下錯誤。

error C2440: 'return': cannot convert from'std::_Array_const_iterator<_Ty,16384>' to 'std::size_t'

我沒有在Linux中遇到上述錯誤。 我是否缺少特定於Visual Studio的內容?

問題可能源於std::begin()在Linux上返回了一個指針,並在Windows中返回了一個正確的迭代器。 這加上一些錯誤。

如果將beginend作為便利函數添加到類中,則如下所示:

template <size_t N> struct Memchunk {
    uint8_t* begin() { return buf.data(); }
    uint8_t* end() { return buf.data()+N; }
    const uint8_t* begin() const { return buf.data(); }
    const uint8_t* end() const { return buf.data()+N; }
    // rest not shown
};

然后left()可以實現為:

    size_t left() const { return end() - last; }

可能會強制取消警告

現在可以在成員初始化列表中使用begin()初始化pos成員

這是Visual Studio插入額外的類型/調試信息。 有時這使其與標准算法不兼容。 就是說,這是您為運行/不足檢測中一些非常出色的陣列所付出的代價,因此可以原諒。
幸運的是,解決方法很容易...

使用:std :: distance http://en.cppreference.com/w/cpp/iterator/distance

只要記住要反轉參數ab == std :: distance(b,a)

讓我知道這是否無效。

-----------修正案-------------

我只是嘗試了您提供的示例,並意識到這不是真正的問題(盡管您會發現距離比迭代器算法更可移植)。 問題仍然是調試信息,但是您需要修復“ char * X = begin(buf)”

而是使用&array [0]

這為我編譯

template <size_t N> struct Memchunk 
{
public:
    Memchunk(Memchunk *next_chunk)
        : pos(&buf[0])
        , last(pos)
        , knext(next_chunk)
        , next(nullptr) 
        {
        }

    size_t len() const { return distance(pos,last); }
    size_t left() const { return std::distance(last,buf); }
    void reset() { pos = last = std::begin(buf); }
    std::array<uint8_t, N> buf;
    uint8_t *pos, *last;
    Memchunk *knext;
    Memchunk *next;
    static const size_t size = N;
};

(順便說一句,您是否有充分的理由不使用std :: list?請在下面嘗試這種方法)

template <size_t N> struct MemchunkImp 
{
public:
    MemchunkImp()
        : pos(&buf[0])
        , last(pos)
        {
        }

    size_t len() const { return distance(pos,last); }
    size_t left() const { return std::distance(last,buf); }
    void reset() { pos = last = std::begin(buf); }
    std::array<uint8_t, N> buf;
    uint8_t *pos, *last;
    static const size_t size = N;
};

template <size_t N> using Memchunk = std::list<MemchunkImp<N>>;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM