Объясните реализацию оператора вызова функции в boost value_factory.
Я пытаюсь понять ускоренную реализацию шаблона проектирования фабрики. Boost предоставляет два типа фабрик: один для типов указателей, а другой для семантики значений. Я могу немного понять шаблонный класс value_factory. Однако я столкнулся с трудностью понять, какoperator()(..)
определяется вне класса и пространства имен.
Ниже приведена ссылка на полный код: https://github.com/boostorg/functional/blob/7516442815900430cc9c4a6190354e11bcbe72dd/include/boost/functional/value_factory.hpp .
Фрагмент кода после удаления множества включений.
# ifndef BOOST_PP_IS_ITERATING
namespace boost
{
template< typename T > class value_factory;
template< typename T >
class value_factory
{
public:
typedef T result_type;
value_factory()
{ }
}; // value_factory
template< typename T > class value_factory<T&>;
} // namespace boost
# else // defined(BOOST_PP_IS_ITERATING)
template< BOOST_PP_ENUM_PARAMS(0, typename T) >
inline result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(0, T, &a)) const
{
return result_type(BOOST_PP_ENUM_PARAMS(N,a));
}
# endif // defined(BOOST_PP_IS_ITERATING)
Этот код взят из версии boost 1.71.
Я хотел бы понять, какую роль здесь играет
- Это вне класса
- Определяется во 2-м условном блоке
# else // defined(BOOST_PP_IS_ITERATING)
Согласно моему пониманию, функция-членoperator()(...)
должен был быть внутри класса.
1 ответ
Он определен внутри класса. Хитрость в том, что заголовочный файл включает в себя самого себя и использует макро-магию, чтобы в конечном итоге завершить рекурсию.
В конце определения класса есть это#include BOOST_PP_ITERATE()
строка, и она будет рекурсивно#include
себя до тех пор, покаBOOST_PP_IS_ITERATING
является#define
д. Результат этого включения t пойдет туда, где отмечено:
# define BOOST_PP_FILENAME_1 <boost/functional/value_factory.hpp>
# define BOOST_PP_ITERATION_LIMITS (0,BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY)
# include BOOST_PP_ITERATE() // <- operator() definition goes here
}; // end of class [my remark]
template< typename T > class value_factory<T&>;
// forbidden, would create a dangling reference
} // namespace boost [my remark]
# define BOOST_FUNCTIONAL_VALUE_FACTORY_HPP_INCLUDED
# else // defined(BOOST_PP_IS_ITERATING)
// the operator definition in header
Если скомпилировано сg++ -E
вы также можете увидеть результат:
namespace boost {
template<class T>
class value_factory;
template<class T>
class value_factory {
public:
typedef T result_type;
template<class... Args>
result_type operator()(Args&&... args) const {
return result_type(std::forward<Args>(args)...);
}
# 99 "/home/ted/local/include/boost/functional/value_factory.hpp"
};
template<class T>
class value_factory<T&> { };
}