从原始指针创建const_iterator会在 macOS 上产生编译错误

Creating const_iterator from raw pointer yields compilation error on macOS

本文关键字:macOS 错误 编译 会在 iterator 指针 原始 创建 const      更新时间:2023-10-16

我有代码,当它在macOS(Sierra 10.12.4(上使用libstdc++库编译时曾经工作过。我现在切换到libc++,它给出了编译时错误:

main.cpp:41:44: error: calling a private constructor of class 'std::__1::__wrap_iter<const unsigned char *>'
        std::vector<uint8_t>::const_iterator i1 = std::vector<uint8_t>::const_iterator(data);
                                                  ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/iterator:1239:31: note: declared private here
    _LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}
                              ^
main.cpp:42:44: error: calling a private constructor of class 'std::__1::__wrap_iter<const unsigned char *>'
        std::vector<uint8_t>::const_iterator i2 = std::vector<uint8_t>::const_iterator(data+n);
                                                  ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/iterator:1239:31: note: declared private here
    _LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}
                              ^
2 errors generated.

显然,const_iterator采用原始数据指针的构造函数现在在macOS的libc++库中是私有的。

下面的代码在编译为 g++ main.cpp -std=c++11 时失败,在编译为 g++ main.cpp -std=c++11 -stdlib=libstdc++ 时成功:

#include <iostream>
#include <vector>
 class Blob {
        public:
            size_t size() const { return (end_-begin_); }
            uint8_t operator[](size_t pos) const { return *(begin_+pos); }
            const uint8_t* data() const { return &(*begin_); }
            Blob(const Blob& b):begin_(b.begin_), end_(b.end_){}
            Blob(const std::vector<uint8_t>::const_iterator& begin, 
                const std::vector<uint8_t>::const_iterator& end):
                begin_(begin), end_(end){}
            Blob& operator=(const Blob& b)
            {
                if (this != &b)
                {
                    begin_ = b.begin_;
                    end_ = b.end_;
                }
                return *this;
            }
            std::vector<uint8_t>::const_iterator begin() const 
            { return begin_; }
            std::vector<uint8_t>::const_iterator end() const
            { return end_; }
        protected:
            std::vector<uint8_t>::const_iterator begin_, end_;
            Blob() = delete;
        };

int main()
{
    std::cout << "hello" << std::endl;
    int n = 100;
    uint8_t *data = new uint8_t(n);
    Blob b(std::vector<uint8_t>::const_iterator(data), 
        std::vector<uint8_t>::const_iterator(data+n));
}

如何使它与libc++一起编译?

你的Blob似乎是一个粗略的gsl::span<const std::uint8_t>

将其替换为span . 如果有必要,请自己编写。 y9u 如何使用您的Blob代码违反了C++标准。

如果做不到这一点,请在跨度方面重新实现 Blob。 如果必须,让 ctor 采用矢量迭代器,但将指针存储在跨度中。

如果做不到这一点,

        Blob(const std::vector<uint8_t>::const_iterator& begin, 
            const std::vector<uint8_t>::const_iterator& end
        ):
          Blob(&*begin, &*end)
        {}
        Blob(std::uint8_t const*begin,std::uint8_t const*end):
          begin_(begin), end_(end)
        {}
        uint8_t const* begin() const 
        { return begin_; }
        uint8_t const* end() const
        { return end_; }
        std::uint8_t const* begin_;
        std::uint8_t const* end_;