I'm trying to use boost::any_range
(with random access tag) in some legacy code, but found that it does not like lambdas. Compilation error seems to complain about the lack of default constructor for lambda objects. Is this expected behavior? Is it by design? I'm on MSVC C++17 with boost version 1.66.
Documentation mentions that transformed_range has the same category as input range:
The problem is obviously in somewhere in boost::any_range
, because if I just use auto, it works (cf rngneg_auto
below)
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/any_range.hpp>
#include <iostream>
#include <vector>
using boost::adaptors::transformed;
using double_range = boost::any_range<const double
, boost::random_access_traversal_tag
, const double>;
struct negate
{
constexpr double operator() (const double x) const
{
return -x;
}
};
int main(int argc, char** argv)
{
const std::vector<double> v{ 1.0, 2.0, 3.0 };
// this works
const auto rngneg_auto = v | transformed([](double x) { return -x; });
std::cout << "Second element is " << rngneg_auto[1] << std::endl;
// ... and this
const double_range rngneg = v | transformed(negate());
std::cout << "Second element is " << rngneg[1] << std::endl;
#if 0
// but not that
const double_range rngneg_lambda = v | transformed([](double x) { return -x; });
std::cout << "Second element is " << rngneg_lambda[1] << std::endl;
#endif
return 0;
}
For the first two cases, the program prints
Second element is -2
Second element is -2
Third is a compilation error (I think it's because lambdas aren't default-constructible):
1>\boost.org\boost\1.66.0\include\boost\optional\optional.hpp(733): error C2280: 'main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65> &main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>::operator =(const main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65> &)': attempting to reference a deleted function
1> ***: note: see declaration of 'main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>::operator ='
1>\boost.org\boost\1.66.0\include\boost\optional\optional.hpp(733): note: while compiling class template member function 'void boost::optional_detail::optional_base<T>::assign_value(main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65> &&)'
1> with
1> [
1> T=main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>
1> ]
1>\boost.org\boost\1.66.0\include\boost\optional\optional.hpp(262): note: see reference to function template instantiation 'void boost::optional_detail::optional_base<T>::assign_value(main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65> &&)' being compiled
1> with
1> [
1> T=main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>
1> ]
1>\boost.org\boost\1.66.0\include\boost\optional\optional.hpp(831): note: see reference to class template instantiation 'boost::optional_detail::optional_base<T>' being compiled
1> with
1> [
1> T=main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>
1> ]
1>\boost.org\boost\1.66.0\include\boost\range\detail\default_constructible_unary_fn.hpp(48): note: see reference to class template instantiation 'boost::optional<F>' being compiled
1> with
1> [
1> F=main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>
1> ]
1>\boost.org\boost\1.66.0\include\boost\utility\detail\result_of_iterate.hpp(70): note: see reference to class template instantiation 'boost::range_detail::default_constructible_unary_fn_wrapper<F,R>' being compiled
1> with
1> [
1> F=main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>,
1> R=double
1> ]
1>\boost.org\boost\1.66.0\include\boost\utility\detail\result_of_iterate.hpp(43): note: see reference to class template instantiation 'boost::detail::cpp0x_result_of<F (T0)>' being compiled
1> with
1> [
1> F=const boost::range_detail::default_constructible_unary_fn_wrapper<main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>,double> &,
1> T0=const double &
1> ]
1>\boost.org\boost\1.66.0\include\boost\mpl\eval_if.hpp(41): note: see reference to class template instantiation 'boost::result_of<const UnaryFunc &(const double &)>' being compiled
1> with
1> [
1> UnaryFunc=boost::range_detail::default_constructible_unary_fn_wrapper<main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>,double>
1> ]
1>\boost.org\boost\1.66.0\include\boost\iterator\iterator_adaptor.hpp(154): note: see reference to class template instantiation 'boost::mpl::eval_if<boost::is_same<T,boost::iterators::use_default>,DefaultNullaryFn,boost::mpl::identity<T>>' being compiled
1> with
1> [
1> T=boost::iterators::use_default,
1> DefaultNullaryFn=boost::result_of<const boost::range_detail::default_constructible_unary_fn_wrapper<main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>,double> &(const double &)>
1> ]
1>\boost.org\boost\1.66.0\include\boost\iterator\transform_iterator.hpp(55): note: see reference to class template instantiation 'boost::iterators::detail::ia_dflt_help<Reference,boost::result_of<const UnaryFunc &(const double &)>>' being compiled
1> with
1> [
1> Reference=boost::iterators::use_default,
1> UnaryFunc=boost::range_detail::default_constructible_unary_fn_wrapper<main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>,double>
1> ]
1>\boost.org\boost\1.66.0\include\boost\iterator\transform_iterator.hpp(81): note: see reference to class template instantiation 'boost::iterators::detail::transform_iterator_base<UnaryFunc,Iterator,Reference,Value>' being compiled
1> with
1> [
1> UnaryFunc=boost::range_detail::default_constructible_unary_fn_wrapper<main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>,double>,
1> Iterator=std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<double>>>,
1> Reference=boost::iterators::use_default,
1> Value=boost::iterators::use_default
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.14.26428\include\xutility(652): note: see reference to class template instantiation 'boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<F,R>,It,boost::iterators::use_default,boost::iterators::use_default>' being compiled
1> with
1> [
1> F=main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>,
1> R=double,
1> It=std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<double>>>
1> ]
1>\boost.org\boost\1.66.0\include\boost\iterator\iterator_categories.hpp(120): note: see reference to class template instantiation 'std::iterator_traits<Iterator>' being compiled
1> with
1> [
1> Iterator=boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>,double>,std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<double>>>,boost::iterators::use_default,boost::iterators::use_default>
1> ]
1>\boost.org\boost\1.66.0\include\boost\range\iterator_range_core.hpp(156): note: see reference to class template instantiation 'boost::iterators::iterator_traversal<IteratorT>' being compiled
1> with
1> [
1> IteratorT=boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>,double>,std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<double>>>,boost::iterators::use_default,boost::iterators::use_default>
1> ]
1>\boost.org\boost\1.66.0\include\boost\range\iterator_range_core.hpp(436): note: see reference to class template instantiation 'boost::iterator_range_detail::pure_iterator_traversal<IteratorT>' being compiled
1> with
1> [
1> IteratorT=boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>,double>,std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<double>>>,boost::iterators::use_default,boost::iterators::use_default>
1> ]
1>\boost.org\boost\1.66.0\include\boost\range\adaptor\transformed.hpp(44): note: see reference to class template instantiation 'boost::iterator_range<boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<F,R>,It,boost::iterators::use_default,boost::iterators::use_default>>' being compiled
1> with
1> [
1> F=main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>,
1> R=double,
1> It=std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<double>>>
1> ]
1>***: note: see reference to class template instantiation 'boost::range_detail::transformed_range<main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>,const std::vector<double,std::allocator<_Ty>>>' being compiled
1> with
1> [
1> _Ty=double
1> ]
1>***: note: 'main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65> &main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65>::operator =(const main::<lambda_6f21fa0f6ab2ea01b2b99a85be3eab65> &)': function was explicitly deleted
Aucun commentaire:
Enregistrer un commentaire