为何boost::function_output_iterator不满足std::output_iterator概念?
关于boost::function_output_iterator与std::output_iterator概念不兼容的问题
我原本认为boost::function_output_iterator符合C++20的std::output_iterator概念,但实际测试发现并非如此,测试代码如下:
#include <boost/iterator/function_output_iterator.hpp> template<std::output_iterator<int> IntOutIter> void f(IntOutIter outputIterator){} int main(int argc, char const *argv[]) { f(boost::make_function_output_iterator([](int i){})); return 0; }
注:template<std::output_iterator<int> IntOutIter>的写法参考了《如何声明接受T类型output_iterator的模板函数?》
使用clang++ -std=c++20 function-output-iterator.cpp编译时会报错,错误信息如下:
error: no matching function for call to 'f' note: candidate template ignored: constraints not satisfied [with IntOutIter = function_output_iterator<(lambda at function-output-iterator.cpp:11:42)>] note: because 'std::output_iterator<boost::iterators::function_output_iterator<(lambda at function-output-iterator.cpp:11:42)>, int>' evaluated to false note: because 'boost::iterators::function_output_iterator<(lambda at function-output-iterator.cpp:11:42)>' does not satisfy 'input_or_output_iterator' note: because 'boost::iterators::function_output_iterator<(lambda at function-output-iterator.cpp:11:42)>' does not satisfy 'weakly_incrementable' note: because 'iter_difference_t<function_output_iterator<(lambda at function-output-iterator.cpp:11:42)>>' (aka 'void') does not satisfy '__is_signed_integer_like' note: because 'void' does not satisfy 'signed_integral' note: because 'void' does not satisfy 'integral' note: because 'is_integral_v<void>' evaluated to false note: and 'void' does not satisfy '__is_signed_int128' note: because 'same_as<void, __int128>' evaluated to false note: because '__detail::__same_as<void, __int128>' evaluated to false note: because 'std::is_same_v<void, __int128>' evaluated to false note: and 'same_as<void, __max_diff_type>' evaluated to false note: because '__detail::__same_as<void, std::ranges::__detail::__max_diff_type>' evaluated to false note: because 'std::is_same_v<void, std::ranges::__detail::__max_diff_type>' evaluated to false 1 error generated.
疑似原因
我推测问题出在boost::function_output_iterator的类型定义上:
typedef void difference_type;
而C++标准对迭代器概念有明确要求:
- 要满足
std::output_iterator,必须先满足input_or_output_iterator,进而满足weakly_incrementable概念 std::iter_difference_t<T>会直接关联迭代器的difference_type- 标准规定
weakly_incrementable要求is-signed-integer-like<iter_difference_t<I>>必须成立
业内通用的合理实现是将difference_type定义为ptrdiff_t而非void。
临时解决方案与Boost文档矛盾
我发现修改模板声明为以下形式可以正常编译:
-template<std::output_iterator<int> IntOutIter> +template<typename IntOutIter> void f(IntOutIter outputIterator){}
但这种写法会丢失C++ Concepts的核心优势:无法通过约束明确泛型类型的操作要求,也无法在类型不匹配时给出清晰的错误提示。
另外,Boost文档明确声称:
function_output_iterator是Writable和Incrementable迭代器概念的模型。
但根据标准,Incrementable概念要求满足weakly_incrementable,而boost::function_output_iterator显然不满足这一点。
核心问题
这到底是怎么回事?
- 是
boost::function_output_iterator的实现存在错误? - 还是我本就不应该将它当作
std::output_iterator使用? - Boost的文档描述是否存在错误?
内容的提问来源于stack exchange,提问作者nh2
相关产品推荐
相关产品推荐

