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

ram*_*dav 7 c++ boost

我见过的提升实现了一个漂亮的帽子戏法,他们以某种方式使用()运算符重载的类boost ::系统:: ERROR_CODE的实例计算为一个布尔值

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;
}
...
}
Run Code Online (Sandbox Code Playgroud)

这导致可以检查这样的错误

...
boost::system::error_code err

some_boost_func(err);
if(err)
{
    //handle error
}
....
Run Code Online (Sandbox Code Playgroud)

所以我一直在问自己..那里发生了什么?这似乎在某种程度上与函数指针的使用有关......如果我调用会发生什么,这会err评估函数本身还是函数指针?但是void (*unspecified_bool_type)();函数如何返回一个值

return m_val == 0 ? 0 : unspecified_bool_true;
Run Code Online (Sandbox Code Playgroud)

AnT*_*AnT 15

它确实与函数指针的核心功能相关很少(或没有).这是一个技巧,允许人们为类编写一个"安全"类似布尔的转换.

当人们希望某个类在if(并且通常在逻辑上下文中)可用时,通常可以将其转换为bool.如在

class Error {
public:
  operator bool() const { /* whatever */ }
};
Run Code Online (Sandbox Code Playgroud)

现在你可以做到

Error err;
...
if (err) // automatically intepreted as `if (err.operator bool())`
  ...
Run Code Online (Sandbox Code Playgroud)

但是,由于bool类型是C++中的一个整体类型,当有人意外地写出类似的内容时,这可能会导致不良后果

int i = err;
Run Code Online (Sandbox Code Playgroud)

或者err在算术表达式中使用并且它静静地编译.

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

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

这是更好的,因为可以使用它if,但一个人不能犯下以前的错误int.即

 if (err) // automatically interpreted as `if (err.operator void *() != 0)`
   ...
Run Code Online (Sandbox Code Playgroud)

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

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

void *p = err;
Run Code Online (Sandbox Code Playgroud)

要么

free(err);
Run Code Online (Sandbox Code Playgroud)

它会安静地编译.这也是不可取的.

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

在某些情况下,人们更进一步,使用更"异国情调"的指针类型:指向类成员类型的指针.但是对于大多数应用程序来说,指向函