- PVSM.RU - https://www.pvsm.ru -
Временами от C++ хочется более гибкого механизма параметризации функций. Например, есть у нас функция с двумя обязательными параметрами и большим количеством необязательных.
bool foo(int important, int& pOut, int sometimes = 1, int occasionally = 2, int rarely = 3)
{
//...
}
Проблемы здесь могут быть следующие
Проблемы эти можно решить по-разному: передавать в качестве параметра структуру, использовать перегрузку функций или даже функции с разными именами… Boost предлагает еще один вариант решения.
Это именованные параметры [1]. Больше мы не привязаны к порядку следования параметров, возможность же задавать осознанные имена при вызове существенно снижает вероятность ошибок. В качестве дополнительного бонуса получаем возможность использовать одни параметры при вычислении значения по умолчанию других.
В качестве примера рассмотрим, как можно определить функцию foo с использованием предлагаемого механизма (имя изменим на namedParametersFoo, чтобы не было путаницы). Для начала подключаем заголовочный файл boost и определяем имена параметров с помощью специального макроса. Обратите внимания — никаких знаков препинания.
#include <boost/parameter.hpp>
BOOST_PARAMETER_NAME(important)
BOOST_PARAMETER_NAME(pOut)
BOOST_PARAMETER_NAME(sometimes)
BOOST_PARAMETER_NAME(occasionally)
BOOST_PARAMETER_NAME(rarely)
далее задаем функцию
BOOST_PARAMETER_FUNCTION(
(bool),
namedParametersFoo,
tag,
(required
(important, *)
(in_out(pOut), *)
)
(optional
(sometimes, *, important * 2)
(occasionally, *, 300)
(rarely, *, 400)
)
)
{
// Тело функции
}
Макросу передается четыре параметра, разделяемых запятыми
Список параметров имеет свою структуру. Также, заметьте, знаков препинания практически никаких — есть только запятые при определении непосредственных параметров.
Вначале идет блок required. Как следует из названия, он содержит список обязательных параметров. Каждый параметр должен быть помещен в круглые скобки. Для определения обязательного параметра необходимо задать его имя и ограничения типа. В данной статье механизм ограничения типов не рассматривается, поэтому будем просто использовать звездочку. Подробнее на эту тему можно почитать здесь [1].
Затем следует блок необязательных параметров. Здесь при определении каждого параметра появляется дополнительная возможность задать значение по умолчанию. Как видно из примера выше, можно использовать в выражениях остальные параметры.
Собственно все. Функция поддерживает вызовы «по старинке» — как если бы была определена с обычными необязательными параметрами. Т.е. как будто заработал вариант
bool newFoo(int important, int& pOut, int sometimes = important * 2, int occasionally = 2, int rarely = 3)
{
//...
}
newFoo не скомпилируется из-за зависимости параметра sometimes от important
Т.е. можно использовать namedParametersFoo так
int s = 0;
namedParametersFoo(1, s, 1, 1, 1);
namedParametersFoo(1, s, 1, 1);
namedParametersFoo(1, s, 1);
namedParametersFoo(1, s);
Но это еще не все! Задействовав именованные параметры, мы освобождаем себя как от порядка следования аргументов, так и от обязательных ненужных значений по умолчанию. Единственное неудобство — требуется добавлять знак подчеркивания вначале имен.
namedParametersFoo(_sometimes = 1, _important = 111, _pOut = s);
Итак, что в этом примере нового хорошего
Несмотря на то, что появилась возможность изменять позицию обязательных параметров и даже смешивать их с необязательными, все продолжает контролироваться на этапе компиляции, т.е. следующий код
namedParametersFoo(_sometimes = 1, _pOut = s);
не соберется — пропущен необходимый параметр _important
На этом все. Хочется добавить, что механизм не самый простой и очевидный, поэтому если получается обойти проблему стандартными средствами языка, то лучше так и делать. К тому же применение именованных параметров boost может негативно сказаться на времени компиляции. Но если все обходные пути получаются кривыми, а boost уже и так используется в проекте — польза однозначно будет.
Автор: vadim_ig
Источник [2]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/55283
Ссылки в тексте:
[1] именованные параметры: http://www.boost.org/doc/libs/1_55_0/libs/parameter/doc/html/index.html
[2] Источник: http://habrahabr.ru/post/213015/
Нажмите здесь для печати.