[英]Why does Clang not like boost::transform_iterator?
使用Clang 8.0.1和Boost 1.70,以下程序
// transform.cpp
#include <vector>
#include <algorithm>
#include <iostream>
#include <boost/iterator/transform_iterator.hpp>
struct Foo
{
int x;
};
struct XGetter
{
auto operator()(const Foo& foo) const noexcept { return foo.x; }
};
int main()
{
const std::vector<Foo> foos {{1}, {2}, {3}};
using boost::make_transform_iterator;
const auto first = make_transform_iterator(foos.cbegin(), XGetter {});
const auto last = make_transform_iterator(foos.cend(), XGetter {});
std::cout << *std::max_element(first, last) << std::endl;
}
無法編譯
$ clang++ -std=c++14 -o transform transform.cpp
/usr/local/Cellar/llvm/8.0.1/bin/../include/c++/v1/algorithm:2494:5: error: static_assert failed due to requirement
'__is_forward_iterator<boost::iterators::transform_iterator<XGetter, std::__1::__wrap_iter<const Foo *>,
boost::use_default, boost::use_default> >::value' "std::max_element requires a ForwardIterator"
static_assert(__is_forward_iterator<_ForwardIterator>::value,
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/Cellar/llvm/8.0.1/bin/../include/c++/v1/algorithm:2512:19: note: in instantiation of function template
specialization 'std::__1::max_element<boost::iterators::transform_iterator<XGetter, std::__1::__wrap_iter<const
Foo *>, boost::use_default, boost::use_default>, std::__1::__less<int, int> >' requested here
return _VSTD::max_element(__first, __last,
^
transform.cpp:24:24: note: in instantiation of function template specialization
'std::__1::max_element<boost::iterators::transform_iterator<XGetter, std::__1::__wrap_iter<const Foo *>,
boost::use_default, boost::use_default> >' requested here
std::cout << *std::max_element(first, last) << std::endl;
^
1 error generated.
我的印象是boost :: transform_iterator繼承了它所建模的迭代器的迭代器類別。 怎么了?
(C ++ 20之前的)標准需要前向或后向迭代器:
由於您的轉換按值返回,因此transform_iterator
無法滿足這兩個要求。 因此,它只能廣告自己作為輸入迭代器。
解決方法是更改XGetter
以通過引用返回,或使用std::mem_fn(&Foo::x)
為您完成此操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.