I am trying to understand the boost implementation of factory design pattern. Boost provides two types of factory one for pointer types and other for value semantics. I am able to understand a little about the template value_factory class. However I am facing difficulty is understanding how operator()(..)
is defined outside class and namespace.
Below is the link to complete code: https://github.com/boostorg/functional/blob/7516442815900430cc9c4a6190354e11bcbe72dd/include/boost/functional/value_factory.hpp
Code snippet after removing lot of includes.
# 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)
This code is from boost version 1.71.
I would like to understand how operator()(...)
plays role here
# else // defined(BOOST_PP_IS_ITERATING)
As per my understanding member function operator()(...)
should have been inside the class.
It is defined inside the class. The trick is that the header file is including itself and is using macro-magic to eventually terminate the recursion.
The end of the class definition has this #include BOOST_PP_ITERATE()
line and it will recursively #include
itself until BOOST_PP_IS_ITERATING
is #define
d. The result of that inclusion t will go where marked:
# 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
If compiled with g++ -E
you can also see the result:
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&> { };
}