Opened 6 years ago
Last modified 6 years ago
#12754 new Bugs
operator| overload for boost::range_details::replace_holder is not SFINAE friendly
Reported by: | Owned by: | Neil Groves | |
---|---|---|---|
Milestone: | To Be Determined | Component: | range |
Version: | Boost 1.61.0 | Severity: | Problem |
Keywords: | SFINAE, ADL, range | Cc: |
Description
If I provide a simple operator | overload for my template class and I provide a class template specializations with for instance a boost range (so that adl adds the boost::range_details namespace for overloads) then the compiler chokes on the non-SFINEA friendly overload
friendly boost::range_details::operator|( SinglePassRange, const replace_holder<BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type> )
Example:
namespace local { template<typename T> struct boo {}; // this overload is not prefered when T is a boost::range::xxx_range template<typename T, typename U> auto operator|(boo<T>, U) { return false; } void finds_local_operator_overload() { std::vector<int> xs; // works like expected and calls local::operator| auto f = boo<decltype(xs)>{} | xs; } void prefers_boost_range_detail_replaced_operator_overload_instead_of_local_operator() { std::vector<int> xs; // compiler error because it tries to call 'boost::range_detail::operator|' auto filtered = xs | boost::adaptors::filtered([](auto &&x){ return x % 2; }); auto f = boo<decltype(filtered)>{} | xs; } }
clang error (msvc reports almost the same):
/xxx/../../thirdparty/boost/1.60.0/dist/boost/range/value_type.hpp:26:70: error: no type named 'type' in 'boost::range_iterator<local::boo<boost::range_detail::filtered_range<(lambda at /xxx/Tests.cpp:221:49), std::vector<int, std::allocator<int> > > >, void>' struct range_value : iterator_value< typename range_iterator<T>::type > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~ /xxx/../../thirdparty/boost/1.60.0/dist/boost/range/adaptor/replaced.hpp:122:40: note: in instantiation of template class 'boost::range_value<local::boo<boost::range_detail::filtered_range<(lambda at /xxx/Tests.cpp:221:49), std::vector<int, std::allocator<int> > > > >' requested here BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type>& f) ^ /xxx/Tests.cpp:222:37: note: while substituting deduced template arguments into function template 'operator|' [with SinglePassRange = local::boo<boost::range_detail::filtered_range<(lambda at /xxx/Tests.cpp:221:49), std::vector<int, std::allocator<int> > > >] auto f = boo<decltype(filtered)>{} | xs;
This can be easily prevented by making the operator overload SFINEA friendly.
Change History (3)
comment:1 by , 6 years ago
Keywords: | range added |
---|
comment:3 by , 6 years ago
Keywords: | SFINAE added; SFINEA removed |
---|---|
Summary: | operator| overload for boost::range_details::replace_holder is not SFINEA friendly → operator| overload for boost::range_details::replace_holder is not SFINAE friendly |
Note:
See TracTickets
for help on using tickets.
https://github.com/boostorg/range/pull/48