[英]C++ operator() overload boost::system::error_code trick
我已經看到了一個提升實現的一個很好的技巧,他們以某種方式使用()運算符的重載來計算類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;
它確實與函數指針的核心功能相關很少(或沒有)。 這是一個技巧,允許人們為類編寫一個“安全”的類似布爾的轉換。
當人們希望某個類在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
返回值。
在某些情況下,人們更進一步,使用更“異國情調”的指針類型:指向類成員類型的指針。 但是對於大多數應用程序來說,指向函
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.