I'm observing a rather weird behaviour of the following piece of code:
#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));
}
The idea here is to isolate the actual representation of a sequence of strings that is received as a parameter by the function f behind an any_range and gsl::string_span (note, the commit changing string_view to string_span has been made a couple of hours ago to GSL).
My original code did not have a const T as Reference template parameter to any_range (it was a simple T) and it crashed during execution. However, that happened only in Release mode an worked fine in Debug or RelWithDebInfo (generated by CMake). I used VS2013/2015 x64. Furthermore, trying to debug the full Release version, adding debug output to the conversion lambda eliminated the crash (my guess is it prevented some inlining). My final working solution is to specify const T as Reference.
However, I'm still wondering why did the crash happen in the first place? Is it the VS compiler bug? Bug in the current implementation of string_span? Or am I simply misusing the boost::any_range?
Aucun commentaire:
Enregistrer un commentaire