Visual Studio

时间:2017-06-29 12:46:01

标签: c++ visual-c++ iterator stdarray

我正在尝试在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特有的内容?

2 个答案:

答案 0 :(得分:0)

问题可能源于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; }

可能有演员沉默警告

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

答案 1 :(得分:0)

这是Visual Studio插入额外的类型/调试信息。这有时会使它与std算法不兼容。也就是说,它是你为一些非常棒的阵列上/下运行检测支付的价格,因此可以原谅。
幸运的是,解决方法很容易......

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

请记住反转参数a-b == std :: distance(b,a)

如果这不起作用,请告诉我。

-----------修正-------------

我只是尝试了你给出的例子,并意识到这不是真正的问题(尽管你会发现距离比迭代算法更便携)。问题仍然是调试信息,但你需要修复&#34; char * X = begin(buf)&#34;

而是使用&amp; 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>>;