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

时间:2014-08-01 20:53:09

标签: c++ algorithm visual-c++ c++11 compiler-errors

在一个更大的项目中,我定义了一个以非常简单的方式定义自己的迭代器的类。到目前为止,我给了我的代码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成功编译。

Here是MSVC的编译器输出(对不起德国编译器输出,我是Windows的新手,我甚至不知道如何更改语言......说实话我带了它几天安装Windows -.-)

让我们分析一下出了什么问题。

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

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

1 个答案:

答案 0 :(得分:3)

解决方案:继承自std::iterator<input_iterator_tag, size_t>

问题是MSVC并不知道你的迭代器是前进一个输入迭代器。这不能从退货类型中扣除。