4

我有自己的工作迭代器来水平或垂直遍历图像中的像素。通过模板参数,它可能是也可能不是( Dobb 博士的const巧妙技巧)。

然后我意识到有一个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 愉快地编译了它

4

2 回答 2

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 : 找不到 CompilerVersion 提示,使用默认编译器版本 'VS2012CTP'
testvc.cpp(1) : info : Ignoring directive '#include',不能在这个 Visual C++ 编译器的在线版本中使用
testvc.cpp(1) : info : 自动导入与此 Visual C++ 编译器在线版本匹配的标准库头文件
Microsoft (R) C/C++ 优化编译器版本 17.00.51025 for x86
版权所有 (C) 微软公司。版权所有。

测试vcpp
--\testvc.cpp(10):致命错误 C1063:编译器限制:编译器堆栈溢出
        --\testvc.cpp(11) : 请参阅对正在编译的类模板实例化“迭代器”的引用
中的内部编译器错误。稍后将提示您向 Microsoft 发送错误报告。

要解决它,请从您的代码中删除以下行:

// 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 : 找不到 CompilerVersion 提示,使用默认编译器版本 'VS2012CTP'
testvc.cpp(1) : info : Ignoring directive '#include',不能在这个 Visual C++ 编译器的在线版本中使用
testvc.cpp(1) : info : 自动导入与此 Visual C++ 编译器在线版本匹配的标准库头文件
testvc.cpp(2) : info : Ignoring directive '#include',不能在这个 Visual C++ 编译器的在线版本中使用
Microsoft (R) C/C++ 优化编译器版本 17.00.51025 for x86
版权所有 (C) 微软公司。版权所有。

测试vcpp
testvc.cpp(64) : info : 文件编译没有错误!

并在 GCC ( http://ideone.com/mEX18H ) 中按预期工作:

结果:成功时间:0s 内存:2896 kB 返回值:0
输入:没有

输出:
0 0
于 2013-05-22T19:52:27.267 回答
1

哦,天哪,那太愚蠢了……玩弄杰瑞的答案让我发现了自己的错误。当然,编译器会进入递归,从而导致堆栈溢出。当我写

// Make base class typedefs available.
typedef typename iterator::value_type value_type;
typedef typename iterator::difference_type difference_type;

我的目的是使基类typedef易于使用。但是没有任何资格的写作iterator是指班级本身,多亏了我typedef上面的其他人,呵呵!

// This is myself...
typedef Iterator<IS_CONST> iterator;

因此,通过正确引用iteratorin std,问题就解决了我可以保留我typedef的 s。

// 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 似乎没有问题。

于 2013-05-23T08:53:46.067 回答