【问题标题】:Using strong typedef as a more lightweight alternative to Boost Parameter library?使用强 typedef 作为 Boost Parameter 库的更轻量级的替代品?
【发布时间】:2012-02-09 12:55:05
【问题描述】:

我经常使用 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 吗? (文档是very brief。)
  • 是否有重要的理由更喜欢 boost 参数库?

【问题讨论】:

  • 取决于你所说的'ok'的意思,我假设它编译并运行,所以有什么问题。我看到了你背后的逻辑,但对我来说这似乎是“错误的”。你可以命名变量和参数是有原因的,所以有一些人在那里明确地将int 转换为Width 只是为了传递它来设置参数width 似乎是错误的。虽然使用set(width w); 等可能很方便,但只有int 你不能这样做。
  • boost 参数用于命名(甚至是可选)参数,而 BOOST_STRONG_TYPEDEF 将创建一个新类型“名称”,该类型可替代原始类型但仍具有不同类型 .

标签: c++ boost boost-parameter


【解决方案1】:

从技术上讲:

  • 有效
  • 它增加了类型安全性

实际上:

我不建议仅仅为了单个函数的参数而创建新类型(除非它是特定于该函数的枚举),类型应该渗透到应用程序中以避免反复使用强制转换。

如果在整个应用程序中使用XYWidthHeight 类型,那么不仅不会进行强制转换,而且您的应用程序也会更安全,并且记录得更好(是的...我是一个类型怪胎)。

现在,对于 Boost.Parameters,这是完全不同的。

Boost.Parameters 可以(可能)在你已经有类型时添加。老实说,虽然我从来没有看到需要。当您的函数变得如此笨拙以至于需要 Boost.Parameters 来调用它们时,您应该修复函数,而不是添加混乱。

【讨论】:

  • 我相信命名参数特别适合高度通用的库,这些库无法为用户决定什么应该被视为“混乱”,并且仍然希望重载 Overload Overwhelming 反模式
  • 我认为 boost.parmater 的有效用例是具有许多默认参数的工厂函数
  • @PorkyBrain:在这种情况下,我更喜欢带有命名函数的Builder 模式。让Builder 由最小的强制参数集构造,然后所有可选参数都通过命名函数传递。
【解决方案2】:

使用 BOOST_STRONG_TYPDEF 正在创建一个新类型,其中 boost 参数库用于为参数命名。它使您可以更明确地了解您的功能。例如(来自 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,因为它创建了一个“可用于匹配函数或模板参数”的新类型(同样来自 boost 文档)。

【讨论】:

    猜你喜欢
    • 2010-09-10
    • 2014-04-23
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    • 2013-08-01
    • 1970-01-01
    • 2010-09-22
    相关资源
    最近更新 更多