C ++ operator()重载boost :: system :: error_code技巧

时间:2012-07-11 06:33:11

标签: c++ boost

我已经看到了一个提升实现的一个很好的技巧,它们以某种方式使用()运算符的重载来计算类boost :: system :: error_code的实例为bool值

class error_code
{
...
typedef void (*unspecified_bool_type)();
static void unspecified_bool_true() {}

operator unspecified_bool_type() const  // true if error
{ 
  return m_val == 0 ? 0 : unspecified_bool_true;
}
...
}

这样就可以检查这样的错误

...
boost::system::error_code err

some_boost_func(err);
if(err)
{
    //handle error
}
....

所以我一直在问自己..那里发生了什么? 这似乎与函数指针的使用有某种关系...... 如果我调用err这会对函数本身或函数指针进行评估会发生什么? 但是void (*unspecified_bool_type)();函数如何在

中返回一个值
return m_val == 0 ? 0 : unspecified_bool_true;

1 个答案:

答案 0 :(得分:15)

具体而言, function 指针的核心功能确实很少(或没有)。这是一个技巧,允许人们写一个" safe"类的类似布尔的转换。

当人们想要某个类在if下(通常在逻辑上下文中)可用时,通常可以将其转换为bool。如在

class Error {
public:
  operator bool() const { /* whatever */ }
};

现在你可以做到

Error err;
...
if (err) // automatically intepreted as `if (err.operator bool())`
  ...

但是,由于bool类型是C ++中的整数类型,当有人意外地写出类似

之类的内容时,这可能会导致不良后果
int i = err;

或在算术表达式中使用err并悄然编译。

出于这个原因,在很多情况下,人们更愿意将转换引入指针类型,而不是转换为bool,如

class Error {
public:
  operator void *() const { 
    // Return null pointer for `false` and any non-null pointer for `true`
  }
};

这样做会更好,因为可以在if下使用它,但是人们无法使用int犯下以前的错误。即

 if (err) // automatically interpreted as `if (err.operator void *() != 0)`
   ...

将按预期编译和工作,因为编译器会自动将err对象转换为指针类型。

但是,这样的转换也会自动应用于指针上下文中(除了布尔上下文之外),这意味着仍然会意外地执行

void *p = err;

free(err);

它将悄然编译。这也是不可取的。

为了使意外滥用此类错误类别变得更加困难,最好再使用一些"异国情调"指针类型,就像指向函数的指针一样。这正是您在引用的代码中看到的内容。 unspecified_bool_type用作基于指针的伪布尔类型。为false返回空值,并为unspecified_bool_true返回指向伪true函数的指针。函数unspecified_bool_true永远不会被调用,永远不会被调用。它仅用于保留一些唯一的指针值以用作true返回。

在某些情况下,人们会更进一步,使用更多的异国情调"指针类型:指向类成员类型的指针。但对于大多数应用程序而言,指向功能的指针是“异国情调”。够了。