Почему std:: function:: argument_type устарел?

Я видел на cppreference, что std::function::argument_type устарел на С++ 17. В чем причина этого? И какой документ ISO WG21 предлагал это?

Ответы

Ответ 1

Соответствующие документы P0005R4 (это документ, который был проголосован в проекте стандарта) и P0090R0 (на который ссылается P0005R4).

Цитаты из P0090R0:

Q2. Что не так с result_type и т.д.?

А2. Эти типизированные стили С++ 98/03/TR1 предшествовали decltype и отлично пересылка. Раньше общий код должен был запрашивать информацию от функциональных объектов, прежде чем приспосабливать их. Теперь, ручная связь эта информация не нужна. decltype supersedes result_type, потому что компилятор может просто сообщить, какой результат вызова функциональный объект с конкретными аргументами будет. И совершенный пересылка заменяет семейство arguments_type, поскольку адаптеры могут просто возьмите/сохраните/переместите произвольные аргументы.

На самом деле эти typedefs хуже, чем бесполезны. Они контрпродуктивным, потому что многие вызываемые объекты не имеют их. функция указатели и указатели на участников всегда их не хватало. ptr_fun(), которые были обернуты указателями функций с этими typedefs, недавно удален (см. [1] снова). Самое главное, лямбдам всегда не хватало эти typedefs, и они являются наиболее важными объектами функции все. Родовые лямбды еще более несовместимы.

Это означает, что если пользователь пытается записать общий код посредством используя семейство typedefs result_type, их код не будет общим - он не справится с lambdas, generic lambdas, указателями функций и т.д.

Эти typedefs следует удалить, поскольку они стали активными вредно для современного кода.

Ответ 2

Причина, по которой такие typedefs существуют, такие вещи, как not1, bind1st и друзья, может запрашивать переданные им вызовы и извлекать тип результата вызова вызываемых, его типов аргументов и т.д.

Чтобы сделать их пригодными для использования, много механизмов поддержки, например unary_function, ptr_fun, mem_fun и т.д. Обратите внимание, что все они ограничены адаптацией вызовов, принимающих только один или два аргумента, поэтому они довольно ограничены в этом смысле.

Теперь, когда мы имеем decltype, который можно использовать для вывода возвращаемого типа вызываемого типа, вариативных шаблонов и совершенной пересылки для пересылки произвольного количества аргументов в функции и т.д., механизмы pre-С++ 11 слишком громоздки для использовать.

Stephan T Lavavej впервые предложил избавиться от них на С++ 17 в p0090r0. Соответствующие выдержки из статьи:

Q1. Что вы предлагаете?
* Удаление всех упоминаний result_type, argument_type, first_argument_type и second_argument_type...
* Удаление отрицателей not1() и not2(), которые были задействованы этими Определения типов.

Q2. Что случилось с result_type и т.д.?
A2. Эти типизированные стили С++ 98/03/TR1 предшествовали decltype и совершенную пересылку. Ранее общий код должен был запрашивать информацию из функциональных объектов перед их адаптацией. Теперь ручная передача этой информации не требуется. decltype заменяет result_type, потому что компилятор может просто сообщить, каким будет результат вызова объекта функции с конкретными аргументами. И идеальная пересылка заменяет семейство argument_type, поскольку адаптеры могут просто принимать/хранить/пересылать произвольные аргументы.

Если вы ищете документ для [func.wrap.func], он говорит конкретно об удалении std::function typedefs, о котором вы просите.