Почему 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, о котором вы просите.