为什么 boost::function_output_iterator 不是 std::output_iterator?

问题描述 投票:0回答:1

我希望

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
  • this 表示
    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 文档是错误的?

c++ boost c++-concepts
1个回答
0
投票

这只是一个猜测——我不是那个特定 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 是一个好主意,但实际工作不是我们:-)

© www.soinside.com 2019 - 2024. All rights reserved.