Удаленные функции C++17

Опубликовано: 4 Сентября, 2022

C++17 позволяет писать простой, понятный и выразительный код. Вот некоторые из возможностей, представленных в C++17:

  • Вложенные пространства имен
  • Объявление переменной в if и switch
  • оператор if constexpr
  • Структурированные привязки
  • Свернуть выражения
  • Прямая инициализация списка перечислений

В новой версии C++17 представлено много новых функций, но некоторые возможности удалены или объявлены устаревшими. Они перечислены ниже:

  • Удаление устаревшего оператора ++
  • Удаление регистров
  • Удаление auto_ptr
  • Триграфы
  • бросить (идентификатор типа)
  • Поддержка распределителя в std::function
  • std::pointer_to_unary_function и std::pointer_to_binary_function
  • std::binder1st и std::binder2nd
  • std::bind1st и std::bind2nd
  • Другие функции.

Давайте начнем подробно обсуждать эти функции.

1. Удаление устаревшего оператора ++: Постфиксные и префиксные выражения Increment (++) теперь недействительны для логических операндов, поскольку префиксный и постфиксный оператор ++ были перегружены для типа bool, но в обоих случаях возвращаемое значение для логического аргумента правда. Тип bool не поддерживает полный набор арифметических типов. С момента запуска C++98 этого изменения ждали. В новой версии C++17 он больше не считается арифметическим типом, и эти операторы объявлены устаревшими.

Альтернативы: В качестве альтернативы можно использовать std::exchange , но только там, где допустимо использование постфиксного оператора. Функция обмена заменяет значение объекта новым значением и возвращает старое значение объекта.

2. Удаление регистров: Давным- давно ключевое слово register в C++11 устарело. Ключевое слово register указывает или дает подсказку компилятору, что переменная может быть помещена в регистр для быстрого доступа, или эти переменные могут интенсивно использоваться, чтобы он мог выполнять оптимизацию, сохраняя их в регистре ЦП. Но компиляторы выполняют неявную оптимизацию, и подсказка использовалась редко. Поэтому в новой версии ключевое слово register удалено, хотя ключевое слово по-прежнему зарезервировано для будущих версий.

Синтаксис:

register string s = "Register on GfG"

Альтернативы: нет альтернативы для регистрации, поскольку компилятор выполняет ту же работу автоматически.

3. Удаление auto_ptr: auto_ptr использовался для создания интеллектуального указателя для обработки времени жизни объекта. Он является владельцем объекта, на который ссылается. Когда объект уничтожается, auto_ptr также автоматически уничтожается. Этот интеллектуальный указатель незаметно крадет право собственности на управляемый объект в его конструкторе копирования и копирует назначение из правого аргумента. В результате копия не совпадает с исходным объектом интеллектуального указателя. Из-за этой семантики копирования auto_ptr не работает как CopyConstructible и, следовательно, устарел.

Альтернативы: auto_ptr можно легко заменить на, unique_ptr который также является интеллектуальным указателем с аналогичной работой, но с повышенной безопасностью. Он был представлен в C++11 как прямая замена auto_ptr , поскольку он предоставляет новые функции (удаления) и поддержку массивов. Более того, он допускает только одного владельца указателя ссылки. Таким образом, при использовании unique_ptr для одного ресурса может быть только один unique_ptr , и когда он уничтожается, ресурс автоматически запрашивается. Если будет попытка сделать копию unique_ptr , это вызовет ошибку времени компиляции.

Пример:

unique_ptr<T> p1 (new T);
unique_ptr<T> p2 = p1; 
// Error: can"t copy unique_ptr

4. Триграфы: Триграфы представляют собой группу из трех персонажей. По сути, это специальная последовательность символов, которая используется в качестве альтернативы некоторым символам. Он представлен двумя вопросительными знаками.

Пример:

??- produces ~ 
??= produces #
??/ produces 
??’ produces ^
??( produces [
??) produces ]
??! produces |
??< produces {
??> produces }

Но они вызывают много путаницы, поскольку анализируются перед комментариями и поэтому удаляются в последней версии.

Альтернативы: C++17 не предоставляет никаких альтернатив для Trigraph, поскольку современные клавиатуры имеют все эти функции. Кроме того, он производит много ошибок в коде.

5. throw(typeid): Если какая-либо функция объявлена с типом T, указанным в ее спецификации исключений, функция может генерировать исключения для этого типа или производного от него типа. Это версия спецификации динамического исключения без генерации, которая устарела и теперь удалена. Он был заменен на noexcept , что имеет более ясное значение.

Синтаксис:

throw(typeid, typeid, ...)

Пример:

void throwsInt(int x) throw(int) 
{  
    cout<<"throw function replaced with noexcept :)";  
    if (x == 0) 
       { 
      throw 1;  
       }
}   

Альтернативы: как упоминалось выше, у throw может быть лучшая альтернатива с noexcept . Он указывает, могут ли функции генерировать исключения или нет, без указания их типа. Но используйте его только тогда, когда вызов функции не может вызвать ошибку, иначе программа завершится.

6. Поддержка распределителя в std::function: несколько конструкторов позволяют указать распределитель, используемый для выделения внутренней памяти. У std::function также есть конструкторы, которые принимают аргумент распределителя, но семантика неясна, и есть технические сбои с сохранением распределителя в контексте со стертым типом и последующим восстановлением этого распределителя позже для любых выделений, необходимых во время копирования. назначение. Поэтому эти перегрузки конструктора были удалены в C++17.

Альтернативы: в C++ нет такой функции, которая заменяет распределитель.

7. std::pointer_to_unary_function, std::pointer_to_binary_function: объекты функций std::pointer_to_unary_function , std::pointer_to_binary_function , которые действуют как оболочки вокруг унарных или бинарных функций. Эти функции включают в себя конструктор , который создает новый объект pointer_to_unary_function с предоставленной функцией и функцией operator(), которая вызывает хранимую функцию.

Альтернативы: эти две функции std::function и std::ref заменяют std::pointer_to_unary_function , std::pointer_to_binary_function .

8. std::binder1st и std::binder2nd: это функциональные объекты, которые связывают аргумент с бинарной функцией. Значение параметра передается объекту во время построения и сохраняется внутри объекта. Всякий раз, когда объект функции вызывается через функцию operator(), сохраненное значение передается как один из аргументов, а другой аргумент передается как аргумент оператора(). Результирующий функциональный объект является унарной функцией.

  • binder1st: связывает первый параметр со значением, заданным во время создания объекта.
  • binder2nd: привязывает второй параметр к значению, заданному во время создания объекта.

Альтернативы: Lambdas , std::bind — это две функции, которые могут быть альтернативой для binder1st и binder2nd.

9. std::bind1st и std::bind2nd: это вспомогательные функции, которые создают экземпляры std::binder1st или std::binder2nd, которые связывают заданный аргумент с первым или вторым параметром заданного объекта бинарной функции. Но они бесполезны с введением лямбд в C++11, поэтому они устарели.

10. Другие функции:

  • стд::mem_fun_t,
  • std::mem_fun1_t
  • std::const_mem_fun_t
  • std::const_mem_fun1_t
  • std::mem_fun_ref_t
  • std::mem_fun1_ref_t
  • std::const_mem_fun_ref_t
  • std::const_mem_fun1_ref_t

Это функциональные объекты, которые обертывают указатель на функцию-член без параметров или с одним параметром. Экземпляр класса, чья функция-член для вызова передается как указатель на operator(), т. е. объект, чья функция-член для вызова передается по указателю на оператор вызова для последнего, передается как ссылка. Они устарели, потому что они ограничены функциями-членами либо без аргументов, либо только с одним аргументом, а для обработки указателей или ссылок на экземпляр класса требуются разные функции и объекты функций.

Альтернативы: альтернативой вышеперечисленным функциям является std::mem_fn , которая может обрабатывать функции-члены с любым количеством переменных и не только ссылками или указателями на объекты, но и интеллектуальными указателями.