在一个更大的项目中,我定义了一个以非常简单的方式定义自己的迭代器的类。到目前为止,我给了我的代码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的工作方式。
我不想写下所有这些类型和定义。如果我这样做,迭代器将比基础类本身更大!
答案 0 :(得分:3)
解决方案:继承自std::iterator<input_iterator_tag, size_t>
问题是MSVC并不知道你的迭代器是前进一个输入迭代器。这不能从退货类型中扣除。