我有自己的工作迭代器来水平或垂直地覆盖图像中的像素。通过模板参数,它可以是const
或不是Dr. Dobb's的整洁技巧。)
然后我意识到有一个std::iterator
基类,我认为我会让我的东西更多 STLly 并继承它。
不幸的是,现在 Visual Studio 2012 (版本11.0.60315.01更新2)将不再编译它。我实际上设法得到编译器stackoverflow。这是消息:
错误1错误C1063:编译器限制:编译器堆栈溢出d:\ ... \ source.cpp 42 1 ConsoleApplication3
我课程的一个非常精简的版本看起来像这样:
#include <iterator>
// This comes from the outer image class.
typedef float color_type;
template<bool IS_CONST = false>
struct Iterator : public std::iterator<std::random_access_iterator_tag, color_type>
{
// This is myself...
typedef Iterator<IS_CONST> iterator;
// ... and my variants.
typedef Iterator<true> const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
// Make base class typedefs available.
typedef typename iterator::value_type value_type;
typedef typename iterator::difference_type difference_type;
// My own typedefs to deal with immutability.
typedef value_type const & const_reference;
typedef typename std::conditional<IS_CONST, const_reference, typename iterator::reference>::type reference;
Iterator()
: _position(nullptr),
_step()
{
}
Iterator(value_type * const position, difference_type const step)
: _position(position),
_step(step)
{
}
iterator const operator-(difference_type n) const
{
return iterator(*this) -= n;
}
difference_type operator-(iterator const rhs) const
{
assert(_step == rhs._step);
return (_position - rhs._position) / _step;
}
protected:
value_type * _position;
difference_type _step;
};
int main()
{
float a = 3.141f;
// Instanciate all variants.
Iterator<false> empty;
Iterator<true> const_empty;
Iterator<false> some(&a, 5);
Iterator<true> const_some(&a, 5);
return 0;
}
删除两个operator-
中的任何一个使编译器满意。
有人可以告诉我这里的问题是什么吗?或者甚至更好地为它提供修复?
由于
更新:哦,顺便说一句,GCC 4.7.2 happily compiles it。
答案 0 :(得分:3)
最小例子:
template<bool B>
struct Iterator
{
typedef typename Iterator<B>::some_type some_type ;
int foo();
int foo(some_type n);
};
int main()
{
return 0;
}
http://rise4fun.com/Vcpp/2eQ的输出:
testvc.cpp(1) : info : Could not find CompilerVersion hint, using default compiler version 'VS2012CTP' testvc.cpp(1) : info : Ignoring directive '#include', which cannot be used in this online version of the Visual C++ compiler testvc.cpp(1) : info : Automatically importing the Standard Library headers which match this online version of the Visual C++ compiler Microsoft (R) C/C++ Optimizing Compiler Version 17.00.51025 for x86 Copyright (C) Microsoft Corporation. All rights reserved. testvc.cpp --\testvc.cpp(10) : fatal error C1063: compiler limit : compiler stack overflow --\testvc.cpp(11) : see reference to class template instantiation 'Iterator' being compiled Internal Compiler Error in . You will be prompted to send an error report to Microsoft later.
要解决此问题,请从代码中删除以下行:
// Make base class typedefs available.
typedef typename iterator::value_type value_type;
typedef typename iterator::difference_type difference_type;
然后在Visual C ++(http://rise4fun.com/Vcpp/1pg)中编译:
testvc.cpp(1) : info : Could not find CompilerVersion hint, using default compiler version 'VS2012CTP' testvc.cpp(1) : info : Ignoring directive '#include', which cannot be used in this online version of the Visual C++ compiler testvc.cpp(1) : info : Automatically importing the Standard Library headers which match this online version of the Visual C++ compiler testvc.cpp(2) : info : Ignoring directive '#include', which cannot be used in this online version of the Visual C++ compiler Microsoft (R) C/C++ Optimizing Compiler Version 17.00.51025 for x86 Copyright (C) Microsoft Corporation. All rights reserved. testvc.cpp testvc.cpp(64) : info : File compiled with no errors!
并在GCC(http://ideone.com/mEX18H)中按预期工作:
result: Success time: 0s memory: 2896 kB returned value: 0 input: no output: 0 0
答案 1 :(得分:1)
哦,我的,那是愚蠢的...和jerry's answer一起玩我让我发现了自己的错误。当然编译器会进入递归,从而导致堆栈溢出。我写的时候
// Make base class typedefs available.
typedef typename iterator::value_type value_type;
typedef typename iterator::difference_type difference_type;
我的目的是让基类“typedef
易于使用。但是,在没有任何资格的情况下编写iterator
是指班级本身,感谢我上面的其他typedef
, duh!
// This is myself...
typedef Iterator<IS_CONST> iterator;
因此,通过正确引用iterator
中的std
,问题就解决了和我可以保留typedef
。
// Make base class typedefs available.
typedef std::iterator<std::random_access_iterator_tag, color_type> base_class;
typedef typename base_class::value_type value_type;
typedef typename base_class::difference_type difference_type;
有趣的是,GCC似乎没有问题。