你面臨的問題(除了operator std::string()
返回一個布爾值)是隱式轉換觸發,當你想要和當你不需要。
當編譯器看到s = t
它確定了以下潛在std::operator=
比賽:
// using std::string for compactness instead of the full template
std::string::operator=(std::string const &);
std::string::operator=(char);
現在,t
既不是他們的,所以它試圖轉換的東西,可以適應,發現兩條路徑:轉換爲可以升級到char
或直接轉換爲std::string
的bool。編譯器不能真正決定並放棄。
這是您希望避免提供許多不同轉換運算符的原因之一。任何可以被編譯器隱式調用的東西最終都會在你認爲不應該的時候調用。
這個article專門處理這個問題。該建議是,而不是提供一個轉換到bool
,提供一個轉換到一個成員函數
class testable {
typedef void (testable::*bool_type)();
void auxiliar_function_for_true_value() {}
public:
operator bool_type() const {
return condition() ? &testable::auxiliar_function_for_true_value : 0;
}
bool condition() const;
};
如果這個類的一個實例是一個條件(if (testable())
)編譯器會嘗試,並轉換爲bool_type
,可以是內部使用在條件下使用。
編輯:
的代碼是如何與這個解決方案更加複雜的評論後,可以隨時爲它作爲一個普通的小工具。一旦你提供了代碼的第一部分,複雜性就被封裝在頭文件中。
// utility header safe_bool.hpp
class safe_bool_t;
typedef void (safe_bool_t::*bool_type)();
inline bool_type safe_bool(bool);
class safe_bool_t {
void auxiliar_function_for_true_value() {}
friend bool_type safe_bool(bool);
};
inline bool_type safe_bool(bool)
{
return condition ? &safe_bool_t::auxiliar_function_for_true_value : 0;
}
你的類現在變得更加簡單,而且它本身就是可讀(通過爲功能和類型選擇合適的名稱):
// each class with conversion
class testable {
public:
operator bool_type() {
return safe_bool(true);
}
};
只有當讀者想知道如何safe_bool
成語實現並讀取它們填充的頭部將面臨的複雜性(可在註釋中解釋)
如果你打算繼續'使用命名空間標準;'你爲什麼要繼續澄清'std :: string'? – 2010-02-19 08:33:21