boost::function_output_iterator
是一个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;
但是标准说它需要是
integral
,而不是void
:
output_iterator
需要成为 weakly_incrementable
(通过 input_or_output_iterator
)std::iter_difference_t<T> = ...::difference_type
(在 Boost 代码中将 iter_difference_t
和 difference_type
联系起来)requires is-signed-integer-like<iter_difference_t<I>>
对于weakly_incrementable
常见的建议是将
difference_type
实施为 ptrdiff_t
,而不是 void
:
我知道这可以编译:
-template<std::output_iterator<int> IntOutIter>
+template<IntOutIter>
void
f(IntOutIter outputIterator){}
但它消除了 C++ 的好处
concepts
:限制泛型类型变量以获得更好的错误消息并指示它们应该支持哪些操作。
那么,
function_output_iterator
不应该是output_iterator
吗?
此外,boost 文档声称:
是function_output_iterator
和Writable
迭代器概念的模型。`Incrementable
incrementable
需要weakly_incrementable
,它显然不是一个模型!
那么,带来了什么?
boost::function_output_iterator
实施错误吗?
或者我不应该能够将它用作
output_iterator
,并且 boost 文档是错误的?
这只是一个猜测——我不是那个特定 boost 库的作者(好吧,我不是任何 boost 库的作者......),或者与 boost 的联系比任何其他用户都多。
您链接的 boost 文档页面上的日期是 2006 年的,这表明它相当旧,并且早于 C++20,足以假设在创建库时,他们仍在开发 C++11。
Boost 通常在其文档中谈论很多概念,但它们(通常)不指 C++20 概念。他们使用该术语仅指类型属性表,例如 boost.org/doc/libs/1_85_0/libs/iterator/doc/...。这类似于 C++20 概念,但没有编译器支持。
Boosts 非正式概念和 STL 中的概念甚至可能具有相同的名称,但这并不意味着它们 100% 相同。也许该库的作者还没有时间将内容与 STL 保持一致。也许他们对现有代码存在兼容性问题。或者也许他们不再对该库做任何事情了。
我们都认为使事物符合 STL 是一个好主意,但实际工作不是我们:-)