Visual Studio中的std::transform在使用自己的迭代器时会失败

std::transform in Visual Studio fails using own iterators

本文关键字:迭代器 自己的 失败 中的 Studio std transform Visual      更新时间:2023-10-16

在一个更大的项目中,我定义了一些类,它以一种非常简约的方式定义了自己的迭代器。到目前为止,我给我的代码gcc和clang,他们吃了它,编译后非常高兴。

今天我试图将我的项目移植到MSVC.....嗯…

在意识到MSVC不支持像snprintf或noexcept关键字这样的东西之后,我被困在了下面的部分。事实上,我想我知道哪里出了问题,但我想知道为什么MSVC会这样做,如果有任何"简单"的方法来解决这个问题。

下面是一个极简的例子:

#include <algorithm>
#include <iostream>
#include <vector>
class Test {
public:
    Test(size_t size) : _size(size) {
    };
    class Iterator {
    public:
        Iterator& operator ++() {
            _position++;
            return *this;
        }
        size_t operator *() {
            return _position;
        }
        bool operator !=(const Iterator &rhs) {
            return _position != rhs._position;
        }
    private:
        friend class Test;
        Iterator(size_t position) : _position(position) {};
        size_t _position;
    };
    Iterator begin() {
        return Iterator(0);
    }
    Iterator end() {
        return Iterator(_size);
    }
private:
    size_t _size;
};
int main()
{
    Test t(10);
    for (auto val : t) // however, this works with MSVC
    {
        std::cout << val << std::endl;
    }
    std::vector<size_t> out(10);
    // Here it crashes
    std::transform(t.begin(), t.end(), out.begin(), [] (size_t i) {
        return i;
    });
    return 0;
}

此代码使用clang或gcc编译成功。

这是MSVC的编译器输出(抱歉为德语编译器输出,我是Windows的新手,我甚至不知道如何改变语言…老实说,安装Windows花了我好几天时间。-)

那么我们来分析一下哪里出了问题。

MSVC声明了一些缺失的类型,如'iterator_category'和许多其他东西。但为什么会这样呢?'std::transform()'使用的所有类型实际上都可以通过Iterator类成员的返回类型推断出来,我想这就是clang或gcc的工作方式。

我不想写下所有的类型和定义。如果我这样做,迭代器将比底层类本身大!

解决方案:inherit from std::iterator<input_iterator_tag, size_t>

问题是MSVC不知道你的迭代器是一个前向输入迭代器。