The following example code:
#define BOOST_RESULT_OF_USE_DECLTYPE // does not help
#include <vector>
#include <algorithm>
#include <future>
#include <boost/range/algorithm.hpp>
struct DW {
std::promise<bool> success_;
};
template <class T>
class Pool
{
public:
Pool() : container_{}
{};
public:
typename std::vector<T>::iterator begin() { return container_.begin(); }
typename std::vector<T>::iterator end() { return container_.end(); }
typename std::vector<T>::const_iterator begin() const { return container_.begin(); }
typename std::vector<T>::const_iterator end() const { return container_.end(); }
private:
std::vector<T> container_; ///< holder of elements
};
#define LAMBDA [] (DW& w) { return w.success_.get_future().get(); }
int main()
{
Pool<DW> vec;
auto s = std::count_if(vec.begin(), vec.end(), LAMBDA);
auto b = boost::count_if(vec, LAMBDA);
return (s == b) ? 0 : 1;
}
fails to compile with GCC 4.8.5, 6.2 or 8 :
g++ -g -pthread -std=gnu++0x -Wall -pedantic -Wextra -Wformat=2 -o "ranger" "ranger.cpp" (in directory: /tmp)
In file included from /usr/local/include/boost/iterator/iterator_categories.hpp:15:0,
from /usr/local/include/boost/iterator/iterator_concepts.hpp:10,
from /usr/local/include/boost/range/concepts.hpp:20,
from /usr/local/include/boost/range/algorithm.hpp:29,
from ranger.cpp:6:
/usr/local/include/boost/mpl/eval_if.hpp: In instantiation of ‘struct boost::mpl::eval_if_c<false, boost::range_const_iterator<Pool<DW>, void>, boost::range_mutable_iterator<Pool<DW>, void> >’:
/usr/local/include/boost/range/iterator.hpp:69:17: required from ‘struct boost::range_iterator<Pool<DW>, void>’
/usr/local/include/boost/range/difference_type.hpp:26:12: required from ‘struct boost::range_difference<Pool<DW> >’
/usr/local/include/boost/range/algorithm/count_if.hpp:32:1: required by substitution of ‘template<class SinglePassRange, class UnaryPredicate> typename boost::range_difference<T>::type boost::range::count_if(SinglePassRange&, UnaryPredicate) [with SinglePassRange = Pool<DW>; UnaryPredicate = main()::__lambda5]’
ranger.cpp:34:41: required from here
/usr/local/include/boost/mpl/eval_if.hpp:60:31: error: no type named ‘type’ in ‘boost::mpl::eval_if_c<false, boost::range_const_iterator<Pool<DW>, void>, boost::range_mutable_iterator<Pool<DW>, void> >::f_ {aka struct boost::range_mutable_iterator<Pool<DW>, void>}’
typedef typename f_::type type;
^
/usr/local/include/boost/mpl/eval_if.hpp: In instantiation of ‘struct boost::mpl::eval_if_c<true, boost::range_const_iterator<Pool<DW>, void>, boost::range_mutable_iterator<const Pool<DW>, void> >’:
/usr/local/include/boost/range/iterator.hpp:69:17: required from ‘struct boost::range_iterator<const Pool<DW>, void>’
/usr/local/include/boost/range/difference_type.hpp:26:12: required from ‘struct boost::range_difference<const Pool<DW> >’
/usr/local/include/boost/range/algorithm/count_if.hpp:41:1: required by substitution of ‘template<class SinglePassRange, class UnaryPredicate> typename boost::range_difference<const SinglePassRange>::type boost::range::count_if(const SinglePassRange&, UnaryPredicate) [with SinglePassRange = Pool<DW>; UnaryPredicate = main()::__lambda5]’
ranger.cpp:34:41: required from here
/usr/local/include/boost/mpl/eval_if.hpp:60:31: error: no type named ‘type’ in ‘boost::mpl::eval_if_c<true, boost::range_const_iterator<Pool<DW>, void>, boost::range_mutable_iterator<const Pool<DW>, void> >::f_ {aka struct boost::range_const_iterator<Pool<DW>, void>}’
ranger.cpp: In function ‘int main()’:
ranger.cpp:34:41: error: no matching function for call to ‘count_if(Pool<DW>&, main()::__lambda5)’
auto b = boost::count_if(vec, LAMBDA);
^
ranger.cpp:34:41: note: candidates are:
In file included from /usr/local/include/boost/range/algorithm.hpp:40:0,
from ranger.cpp:6:
/usr/local/include/boost/range/algorithm/count_if.hpp:41:1: note: template<class SinglePassRange, class UnaryPredicate> typename boost::range_difference<const SinglePassRange>::type boost::range::count_if(const SinglePassRange&, UnaryPredicate)
count_if(const SinglePassRange& rng, UnaryPredicate pred)
^
/usr/local/include/boost/range/algorithm/count_if.hpp:41:1: note: substitution of deduced template arguments resulted in errors seen above
/usr/local/include/boost/range/algorithm/count_if.hpp:32:1: note: template<class SinglePassRange, class UnaryPredicate> typename boost::range_difference<T>::type boost::range::count_if(SinglePassRange&, UnaryPredicate)
count_if(SinglePassRange& rng, UnaryPredicate pred)
^
/usr/local/include/boost/range/algorithm/count_if.hpp:32:1: note: substitution of deduced template arguments resulted in errors seen above
Compilation failed.
and also with clang 5.0.0 (trunk 302784)
$ clang++ -g -pthread -std=c++14 -Wall -pedantic -Wextra -Wformat=2 -o "ranger" "ranger.cpp" (in directory: /tmp)
In file included from ranger.cpp:6:
In file included from /usr/local/include/boost/range/algorithm.hpp:29:
In file included from /usr/local/include/boost/range/concepts.hpp:20:
In file included from /usr/local/include/boost/iterator/iterator_concepts.hpp:10:
In file included from /usr/local/include/boost/iterator/iterator_categories.hpp:15:
/usr/local/include/boost/mpl/eval_if.hpp:60:26: error: no type named 'type' in 'boost::range_mutable_iterator<Pool<DW>, void>'
typedef typename f_::type type;
~~~~~~~~~~~~~^~~~
/usr/local/include/boost/range/iterator.hpp:65:31: note: in instantiation of template class 'boost::mpl::eval_if_c<false, boost::range_const_iterator<Pool<DW>, void>, boost::range_mutable_iterator<Pool<DW>, void> >' requested here
typedef typename mpl::eval_if_c<
^
/usr/local/include/boost/range/difference_type.hpp:28:40: note: in instantiation of template class 'boost::range_iterator<Pool<DW>, void>' requested here
BOOST_DEDUCED_TYPENAME range_iterator<
^
/usr/local/include/boost/range/algorithm/count_if.hpp:31:38: note: in instantiation of template class 'boost::range_difference<Pool<DW> >' requested here
inline BOOST_DEDUCED_TYPENAME boost::range_difference<SinglePassRange>::type
^
ranger.cpp:34:14: note: while substituting deduced template arguments into function template 'count_if' [with SinglePassRange = Pool<DW>, UnaryPredicate = (lambda at ranger.cpp:34:35)]
auto b = boost::count_if(vec, LAMBDA);
^
In file included from ranger.cpp:6:
In file included from /usr/local/include/boost/range/algorithm.hpp:29:
In file included from /usr/local/include/boost/range/concepts.hpp:20:
In file included from /usr/local/include/boost/iterator/iterator_concepts.hpp:10:
In file included from /usr/local/include/boost/iterator/iterator_categories.hpp:15:
/usr/local/include/boost/mpl/eval_if.hpp:60:26: error: no type named 'type' in 'boost::range_const_iterator<Pool<DW>, void>'
typedef typename f_::type type;
~~~~~~~~~~~~~^~~~
/usr/local/include/boost/range/iterator.hpp:65:31: note: in instantiation of template class 'boost::mpl::eval_if_c<true, boost::range_const_iterator<Pool<DW>, void>, boost::range_mutable_iterator<const Pool<DW>, void> >' requested here
typedef typename mpl::eval_if_c<
^
/usr/local/include/boost/range/difference_type.hpp:28:40: note: in instantiation of template class 'boost::range_iterator<const Pool<DW>, void>' requested here
BOOST_DEDUCED_TYPENAME range_iterator<
^
/usr/local/include/boost/range/algorithm/count_if.hpp:40:38: note: in instantiation of template class 'boost::range_difference<const Pool<DW> >' requested here
inline BOOST_DEDUCED_TYPENAME boost::range_difference<const SinglePassRange>::type
^
ranger.cpp:34:14: note: while substituting deduced template arguments into function template 'count_if' [with SinglePassRange = Pool<DW>, UnaryPredicate = (lambda at ranger.cpp:34:35)]
auto b = boost::count_if(vec, LAMBDA);
^
ranger.cpp:34:14: error: no matching function for call to 'count_if'
auto b = boost::count_if(vec, LAMBDA);
^~~~~~~~~~~~~~~
/usr/local/include/boost/range/algorithm/count_if.hpp:32:1: note: candidate template ignored: substitution failure [with SinglePassRange = Pool<DW>, UnaryPredicate = (lambda at ranger.cpp:34:35)]
count_if(SinglePassRange& rng, UnaryPredicate pred)
^
/usr/local/include/boost/range/algorithm/count_if.hpp:41:1: note: candidate template ignored: substitution failure [with SinglePassRange = Pool<DW>, UnaryPredicate = (lambda at ranger.cpp:34:35)]
count_if(const SinglePassRange& rng, UnaryPredicate pred)
^
3 errors generated.
Compilation failed.
Isn't boost::algo(range) supposed to be a drop-in replacement for std::algo(range.begin(), range.end()) ?
Define iterator and const_iterator in your Pool class. The Boost Algorithm library was written before C++11 and it does not use decltype to find out the iterator type. Unfortunately, it is still not updated to use it if available, so you have to define the iterator type. It is a good practice anyway.
template <class T>
class Pool
{
public:
Pool() : container_{}
{};
public:
using iterator = typename std::vector<T>::iterator;
using const_iterator = typename std::vector<T>::const_iterator;
iterator begin() { return container_.begin(); }
iterator end() { return container_.end(); }
const_iterator begin() const { return container_.begin(); }
const_iterator end() const { return container_.end(); }
private:
std::vector<T> container_; ///< holder of elements
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With