Почему boost::function_output_iterator не является std::output_iterator?

Я ожидал, что 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?)

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:

Общие рекомендации — реализовать 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 docs утверждает:

function_output_iterator — это модель концепций Writable и Incrementable Iterator.`

Но инкрементируемый требует weakly_incrementable, образцом которого он явно не является!

Вопрос

Итак, что дает?

boost::function_output_iterator реализовано неправильно?

Или я не должен иметь возможность использовать его как output_iterator, а документы по повышению неверны?

Это всего лишь предположение, но вы смотрели на дату документов по повышению, на которые вы ссылались? Это из 2006 года... Когда boost говорит о «концепциях», они обычно (никогда?) не имеют в виду C++20: для них «концепция» — это просто таблица требований, как boost. org/doc/libs/1_85_0/libs/iterator/doc/…. Возможно, они не удосужились привести это в соответствие с тем, что фактически было превращено в стандарт C++...

Christian Stieber 20.04.2024 22:28

Я думаю, что @ChristianStieber это делает, и это заслуживает ответа.

sehe 20.04.2024 22:40

Эта конкретная часть Boost была написана двадцать четыре года назад и с тех пор почти не менялась.

n. m. could be an AI 21.04.2024 00:14
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
3
80
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это всего лишь предположение — я не являюсь автором этой конкретной библиотеки повышения (ну, я не являюсь автором НИКАКОЙ библиотеки повышения...) и не связан с повышением больше, чем любой другой пользователь.

Дата на странице документации по повышению, на которую вы ссылаетесь, относится к 2006 году, что позволяет предположить, что она довольно старая и предшествует C++20 достаточно давно, чтобы предположить, что на момент создания библиотеки они все еще работали над C++11.

Boost обычно много говорит о концепциях в своей документации, но они (обычно) не ссылаются на концепции C++20. Они используют этот термин для обозначения таблицы свойств типов, например здесь. Это похоже на концепцию C++20, но без поддержки компилятора.

Повышает неформальные концепции и концепции, найденные в STL, могут даже иметь одинаковые имена, но это не значит, что они на 100% одно и то же. Возможно, автор этой библиотеки не нашел времени привести ее в соответствие с STL. Возможно, у них есть проблемы с совместимостью существующего кода. Или, может быть, они больше ничего не делают с этой библиотекой.

Мы все думаем, что сделать вещи совместимыми с STL — отличная идея, но реальную работу делаем не мы :-)

Угу, я вижу. Я не ожидал, что это повысит «концепции» != «концепции» C++. Я думаю, было бы очень полезно, если бы в документации Boost была хотя бы ссылка на страницу , на которую вы ссылались , чтобы можно было сказать, что это разные концепции. Я не знал, насколько «устаревшим» является boost в некоторых аспектах — мой опыт до сих пор сводился к тому, что Boost опережает C++ STL в отношении новых идей и что он обновляется, когда они превращаются в ядро ​​C++. Очевидно, что это не всегда так. Спасибо за ответ!

nh2 21.04.2024 18:07

Непосредственный последующий вопрос: существует ли стандартная современная альтернатива boost:function_output_iterator, которая работает с концепцией std::output_iterator?

nh2 21.04.2024 23:13

@nh2 в эпоху std::ranges они стали известны как источники/приемники и не так популярны. Вы можете прочитать дополнительную информацию и, возможно, полезные советы thephd.dev/output-ranges

sehe 22.04.2024 13:09

Другие вопросы по теме