我已经看到了一个提升实现的一个很好的技巧,它们以某种方式使用()运算符的重载来计算类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;
答案 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
返回。
在某些情况下,人们会更进一步,使用更多的异国情调"指针类型:指向类成员类型的指针。但对于大多数应用程序而言,指向功能的指针是“异国情调”。够了。