Использование сильного typedef в качестве более легкой альтернативы библиотеке параметров Boost? - PullRequest
17 голосов
/ 09 февраля 2012

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

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?

Ответы [ 2 ]

18 голосов
/ 09 февраля 2012

Технически говоря:

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

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

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

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

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

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

2 голосов
/ 09 февраля 2012

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

#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, так как он создает новые типы ", которые можно использовать для сопоставления параметров функции или шаблона" (снова из документации буста).

...