J'essaye d'écrire un operator|
pour ma classe de modèle boo
et tout fonctionne bien jusqu'à ce que la classe de modèle soit un type de gamme boost - comme dans l'exemple un boost::range::filter_range
- adl préfère le boost::range_detail::operator|(SinglePassRange& r, const replace_holder<T>)
au local.Pourquoi adl préfère le 'boost :: range_detail :: operator |' sur l'opérateur local |
Quelqu'un peut-il expliquer pourquoi adl préfère la surcharge de la booster cet espace de noms détaillé sur l'espace de noms local?
#include <vector>
#include <boost/range/adaptors.hpp>
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;
}
}
erreur clang (rapports de MSVC presque les mêmes):
/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;
Les deux opérateurs doivent être pris en compte. mais je suppose que le boost est plus spécialisé que le tien. – Jarod42
Pourquoi les fonctions du modèle 'boost :: range_detail :: replace_holder' sont-elles prises en compte? Il n'y a aucun argument qui ouvre l'espace de noms boost. Il n'y a que le modèle 'T' qui provient de l'espace de nommage boost. Et s'il y a une bonne raison de le prendre en compte, pourquoi les autres fonctions du gabarit Booster de gamme ne sont-elles pas prises en compte? – TimW