这是Visual Studio 2013更新4 C ++优化器错误还是我的代码错误?

时间:2015-07-14 09:30:24

标签: c++ c++11 boost boost-range

自从我更新为1.58和VS2013以来,我一直在软件中看到崩溃。只有在编译器优化开启时,我们才会看到崩溃。使用boost 1.55,没有崩溃。我设法将我遇到的问题与boost::any_range以及我们如何使用它隔离开来。

请参阅下面的示例代码:

#include <boost/range/any_range.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <vector>
#include <memory>
#include <cstdio>

class DummyElement
{
public:
    float f_;
};

using ElementRange = boost::any_range < DummyElement*, boost::bidirectional_traversal_tag >;

using DummyElementUPtr = std::unique_ptr < DummyElement > ;

class BoostAnyTest
{
public:
    BoostAnyTest()
    { 
        for (int i = 0; i < 10; ++i)
        {
            auto element = DummyElementUPtr(new DummyElement());
            _tprintf(_T("BoostAnyTest::ctor() 0x%p\n"), element.get());

            c_.emplace_back(std::tuple<Int, DummyElementUPtr>(i, std::move(element)));
        }
    }

public:
    ElementRange GetAll();

private:
    using _ContainerType = std::vector < std::tuple<Int, std::unique_ptr<DummyElement>> > ;
    _ContainerType    c_;
};


ElementRange
BoostAnyTest::GetAll()
{
    auto transform = [ ] (const _ContainerType::value_type& v) -> DummyElement*
    {
        return std::get<1>(v).get();
    };

    return c_ | boost::adaptors::transformed(transform);
}


int
main()
{
    BoostAnyTest    any;

    auto range = any.GetAll();

    std::for_each(std::begin(range), std::end(range), [ ] (DummyElement* element)
    { 
        _tprintf(_T("TestBoostAnyRange() 0x%p\n"), element);
    });
}

以下是程序输出。 DEBUG版本输出是我所期望的,但优化的RELEASE版本对我来说是一个谜......

DEBUG version output:
BoostAnyTest::ctor() 0x007D0FB0
BoostAnyTest::ctor() 0x007D0E30
BoostAnyTest::ctor() 0x007D0E60
BoostAnyTest::ctor() 0x007D1160
BoostAnyTest::ctor() 0x007D0E90
BoostAnyTest::ctor() 0x007D10A0
BoostAnyTest::ctor() 0x007D0F80
BoostAnyTest::ctor() 0x007D0FE0
BoostAnyTest::ctor() 0x007D1010
BoostAnyTest::ctor() 0x007D1040
TestBoostAnyRange() 0x007D0FB0
TestBoostAnyRange() 0x007D0E30
TestBoostAnyRange() 0x007D0E60
TestBoostAnyRange() 0x007D1160
TestBoostAnyRange() 0x007D0E90
TestBoostAnyRange() 0x007D10A0
TestBoostAnyRange() 0x007D0F80
TestBoostAnyRange() 0x007D0FE0
TestBoostAnyRange() 0x007D1010
TestBoostAnyRange() 0x007D1040

RELEASE version output:
BoostAnyTest::ctor() 0x00BFA358
BoostAnyTest::ctor() 0x00BFA238
BoostAnyTest::ctor() 0x00BFA3E8
BoostAnyTest::ctor() 0x00BFA248
BoostAnyTest::ctor() 0x00BFA258
BoostAnyTest::ctor() 0x00BFA268
BoostAnyTest::ctor() 0x00C2ECB8
BoostAnyTest::ctor() 0x00C2ED98
BoostAnyTest::ctor() 0x00C2EDA8
BoostAnyTest::ctor() 0x00C2ED48
TestBoostAnyRange() 0x00A5FCE0
TestBoostAnyRange() 0x00A5FCE0
TestBoostAnyRange() 0x00A5FCE0
TestBoostAnyRange() 0x00A5FCE0
TestBoostAnyRange() 0x00A5FCE0
TestBoostAnyRange() 0x00A5FCE0
TestBoostAnyRange() 0x00A5FCE0
TestBoostAnyRange() 0x00A5FCE0
TestBoostAnyRange() 0x00A5FCE0
TestBoostAnyRange() 0x00A5FCE0

也许我的代码错了或者它真的是优化器中的错误?任何提示将不胜感激!

1 个答案:

答案 0 :(得分:11)

这是Boost bug 10493(在Boost 1.56中引入,这就是为什么你的代码适用于Boost 1.55)。

解决方法是在您的情况下使用T const作为Reference模板参数:

using ElementRange = boost::any_range <
    DummyElement*,
    boost::bidirectional_traversal_tag,
    DummyElement* const
>;

Example