Объясните реализацию оператора вызова функции в 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.

Я хотел бы понять, какую роль здесь играет

  1. Это вне класса
  2. Определяется во 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&> { };

}
Другие вопросы по тегам