Использование сильного typedef в качестве более легкой альтернативы библиотеке Boost Parameter?

Я часто использую мощную утилиту typedef Boost для повышения безопасности моих программ. Например, написав код следующим образом:

BOOST_STRONG_TYPEDEF(int, X)
BOOST_STRONG_TYPEDEF(int, Y)
BOOST_STRONG_TYPEDEF(int, Width)
BOOST_STRONG_TYPEDEF(int, Height)

struct Rect {
    Rect(X x, Y y, Width w, Height h);
};

// Usage:
Rect rect(X(10), Y(20), Width(800), Height(600));

Сильный typedef здесь улучшает читаемость кода и безопасность. (Компилятор сообщит об ошибке, если аргументы предоставлены в неправильном порядке, чего бы не было, если все аргументы были int.)

Мои вопросы:

  • Можно ли использовать BOOST_STRONG_TYPEDEF для этой цели? (Документация очень короткая.)
  • Есть ли важные причины, чтобы предпочесть библиотеку параметров boost?

Ответы

Ответ 1

С технической точки зрения:

  • он работает
  • добавляет безопасность типов

Практически говоря:

Я бы не рекомендовал создавать новые типы только для одного параметра функции (если он не является перечислением, специфичным для этой функции), типы должны пронизывать приложение, чтобы избежать использования приемов много раз.

Если типы X, Y, Width и Height используются во всем приложении, то не только не будет никакого перевода, но ваше приложение будет намного безопаснее и значительно лучше документировано (да... Я типа урод).

Теперь, что касается Boost.Parameters, это совершенно другое.

Boost.Parameters могут (потенциально) добавляться, когда у вас уже есть типы. Честно говоря, хотя я никогда не видел нужды. Когда ваши функции растут настолько громоздкими, что Boost.Parameters требуется для их вызова, вы должны исправить функции, а не добавлять в беспорядок.

Ответ 2

Использование BOOST_STRONG_TYPDEF создает новый тип, где, поскольку библиотека параметров boost предназначена для указания имен параметрам. Это позволяет вам более четко понимать, что делают ваши функции. Например (из документации по ускорению)

#include <boost/parameter/preprocessor.hpp>

namespace graphs
{
  BOOST_PARAMETER_FUNCTION(
      (void),                // 1. parenthesized return type
      depth_first_search,    // 2. name of the function template

      tag,                   // 3. namespace of tag types

      (required (graph, *) ) // 4. one required parameter, and

      (optional              //    four optional parameters, with defaults
        (visitor,           *, boost::dfs_visitor<>())
        (root_vertex,       *, *vertices(graph).first)
        (index_map,         *, get(boost::vertex_index,graph))
        (in_out(color_map), *,
          default_color_map(num_vertices(graph), index_map) )
      )
  )
  {
      // ... body of function goes here...
      // use graph, visitor, index_map, and color_map
  }
}

Позволяет вам прямо сказать, что ожидается, почти в дизайне по контракту. Однако я считаю, что это усложняет читаемость вашего кода, чтобы сделать его нецелесообразным.

Лично я предпочитаю использовать BOOST_STRONG_TYPEDEF, поскольку он создает новые типы, которые могут использоваться для сопоставления параметров функции или шаблона (опять же из документации по ускорению).