В этом разделе рассказывается, как пользоваться библиотекой.
Рассмотрим следующие функции, которые имеют различные подписи:
const std::string& identity_s(const std::string& x)
{ return x; }
int identity_i_impl(int x) { return x; }
int (&identity_i)(int) = identity_i_impl;
double identity_d_impl(double x) { return x; }
boost::function<double (double)> identity_d = identity_d_impl;
Этот заголовок библиотеки<boost/functional/overloaded_function.hpp
>предоставляет шаблон класса<boost::overloaded_function
>, который создает один перегруженный объект функции, который можно использовать для вызова указанных функций вместо использования отдельных имен функций (см. также<functor.cpp
>и<identity.hpp
>):
boost::overloaded_function<
const std::string& (const std::string&)
, int (int)
, double (double)
> identity(identity_s, identity_i, identity_d);
BOOST_TEST(identity("abc") == "abc");
BOOST_TEST(identity(123) == 123);
BOOST_TEST(identity(1.23) == 1.23);
Обратите внимание, как каждый тип функции передается в качестве параметра шаблона<boost::overloaded_function
>с использованием следующего синтаксиса (этоBoost.Functionпредпочтительный синтаксис):
result-type (argument1-type, argument2-type, ...)
Затем относительные указатели функций, ссылки на функции илимономорфные объекты функциипередаются конструктору<boost::overloaded_function
>, соответствующему порядку заданных параметров шаблона.]В приведенном выше примере<identity_s
>передается в качестве указателя функции (адрес функции автоматически берется из имени функции компилятором),<identity_i
>в качестве ссылки на функцию и<identity_d
>в качестве объекта функции.
Все указанные типы функций должны иметь отличные друг от друга параметры (так что перегруженные вызовы могут быть разрешены этой библиотекой).Для создания перегруженного функционального объекта необходимо указать как минимум два типа функций (потому что перегрузки между одной или нулевой функцией не существует).
Для удобства эта библиотека также предоставляет шаблон функции<boost::make_overloaded_function
>, который позволяет создавать перегруженный объект функции без явного указания типов функций. Типы функций автоматически выводятся из указанных функций, и соответствующее<boost::overloaded_function
>инстанцирование возвращается<boost::make_overloaded_function
>.
Шаблон функции<boost::make_overloaded_function
>может быть полезен при использовании вместе сBoost.Typeof's<BOOST_AUTO
>(или C++11<auto
>). Например,<make_decl.cpp
>и<identity.hpp
>:
BOOST_AUTO(identity, boost::make_overloaded_function(
identity_s, identity_i, identity_d));
BOOST_TEST(identity("abc") == "abc");
BOOST_TEST(identity(123) == 123);
BOOST_TEST(identity(1.23) == 1.23);
Обратите внимание, что объект<identity
>перегруженной функции был создан, указывая только функции<identity_s
>,<identity_i
>,<identity_d
>и без указания типов функций<conststd::string&(const
std::string&)
>,<int(int)
>и<double(double)
>, как требуется вместо<boost::overloaded_function
>. Таким образом,<boost::make_overloaded_function
>обеспечивает более краткий синтаксис в этом контексте по сравнению с<boost::overloaded_function
>.
Другой случай, когда<boost::make_overloaded_function
>может быть полезным, это когда перегруженный объект функции передается шаблону функции, который может содержать конкретный тип<boost::overloaded_function
>с использованием параметра шаблона. Например,<make_call.cpp
>и<identity.hpp
>:
template<typename F>
void check(F identity) {
BOOST_TEST(identity("abc") == "abc");
BOOST_TEST(identity(123) == 123);
BOOST_TEST(identity(1.23) == 1.23);
}
check(boost::make_overloaded_function(identity_s, identity_i, identity_d));
Реализация библиотеки<boost::make_overloaded_function
>используетBoost.Typeofдля автоматического вывода некоторых типов функций. Для составления кода вBoost. Типрежима эмуляции, все типы должны быть надлежащим образом зарегистрированы с использованием<BOOST_TYPEOF_REGISTER_TYPE
>и<BOOST_TYPEOF_REGISTER_TEMPLATE
>, или должны быть включены соответствующиезаголовки Boost.Typeof(см.Boost.Typeofдля получения дополнительной информации). Для приведенных выше примеров достаточно включить заголовокBoost.Typeof, который регистрирует<std::string
>(эта библиотека не требует регистрации<boost::function
>дляBoost.Typeofэмуляции):
#include <boost/typeof/std/string.hpp>