为什么Clang不喜欢boost::transform_iterator?
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 继承了它建模的迭代器的迭代器类别。出了什么问题?
(pre-C++20( 标准需要前向或更强的迭代器:
- 在取消引用时产生真实引用;
- 在取消引用两个相等的迭代器时生成对同一对象的引用(即,没有存储(
由于转换按值返回,因此transform_iterator
无法同时满足这两个要求。因此,它只能将自己宣传为输入迭代器。
解决方法是将XGetter
更改为按引用返回,或者使用为您执行此操作的std::mem_fn(&Foo::x)
。
相关文章:
- 使用std::transform将一个范围的元素添加到另一个范围中
- g++ 为 transform() 的参数生成错误
- 在调试模式下引发C++ "deque iterator not dereferencable"异常
- std::iterator::reference 必须是引用吗?
- 使用 std::transform 将向量向量 (a) 添加到另一个向量向量 (b)
- std::transform 将一个结构数组复制到另一个结构数组
- 为什么unordered_set<string::iterator>不起作用?
- 在 transform() 中调用成员函数
- 如何正确使用 std::transform 和 std::mem_fn?
- 如何在 std::transform 中使用 std::p ow 作为一元函数?
- 造成致命错误:boost/fusion/iterator/equal_to.hpp 没有这样的文件或目录
- 在 C++ 中使用 "transform" 会给出一个错误,指出这未在作用域中声明
- Visual accept std::string from std::byte iterator
- 将 std::transform 与 std::back_inserter 一起使用是否有效?
- 计算一个单词在映射中出现的次数 - 使用 transform() - 调用不匹配
- 使用 std::transform 最终向量保持为空
- C++ 通过 std::transform 的 vector 索引获取向量
- GLM中的Java Matrix4.transform等价物
- 什么是"std::set<int,int>::iterator"?
- 如何使用for_each,transform,Iterator和lambda的某种组合将STD ::集合的字符串转换为小