以下示例代码:
#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;
}
无法使用GCC 4.8.5,6.2或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.
以及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; t boost::algo(range)
应该是std::algo(range.begin(), range.end())
的替补?
答案 0 :(得分:6)
在iterator
课程中定义const_iterator
和Pool
。 Boost算法库是在C ++ 11之前编写的,它不使用decltype
来找出迭代器类型。不幸的是,如果可用,它仍然没有更新使用它,所以你必须定义迭代器类型。无论如何,这是一个很好的做法。
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
};