我观察下面的代码段的一个相当怪异的行为:的boost :: any_range <GSL :: string_span <>>坠毁在Release模式
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/any_range.hpp>
#include <vector>
#include <string>
#include <iostream>
#include "gsl.h"
template <typename T>
using ImmutableValueRange = boost::any_range<T, boost::bidirectional_traversal_tag, /*const*/ T>;
template <typename T, typename C>
ImmutableValueRange<T> make_transforming_immutable_range(const C& container)
{
return container | boost::adaptors::transformed([](const typename C::value_type& v) -> T
{
//std::cout << "trans : " << T{ v }.data() << "\n";
return T{ v };
});
}
void f(ImmutableValueRange<gsl::cstring_span<>> r)
{
for (const auto& c : r) {
std::cout << c.data() << "\n";
}
}
int main()
{
std::vector<std::string> v({ "x", "y", "z" });
f(make_transforming_immutable_range<gsl::cstring_span<>>(v));
}
这里的想法是隔离的实际表现在any_range
和gsl::string_span
(注意,提交更改string_view
到string_span
已在几个小时前提交给GSL)后作为参数通过功能f
接收的一系列字符串。
我原来的代码没有一个const T
为Reference
模板参数any_range
(这是一个简单的T
),并在执行过程中坠毁。然而,这只发生在发布模式下,在Debug或RelWithDebInfo(由CMake生成)中工作正常。我用VS2013/2015 x64。此外,试图调试完整的发布版本,添加调试输出到转换lambda消除了崩溃(我的猜测是它阻止了一些内联)。我的最终工作解决方案是将const T
指定为Reference
。
但是,我仍然想知道为什么是否首先崩溃?它是VS编译器错误吗?目前执行中的错误string_span
?或者我只是在滥用boost::any_range
?
编辑
刚刚建成的版本铿锵3.7.0和行为是相似的(在调试工作正常,并不会崩溃,但没有const T
与-O2
输出垃圾)。所以它看起来不像编译器问题。
祝你好运调试。你试过调试它吗?您可以在发行模式下进行调试。 –
@WarrenP当然。但它在Debug/RelWithDebInfo模式下工作得很好,甚至在Release模式下的lambda中也有一些调试输出,有点让调试真的很难:) – Rostislav