[英]Selective implicit conversions
我有一個Value
類,可以保存各種數據類型的值。
class Value
{
private:
union
{
int Integer;
double Real;
bool Boolean;
};
ValueTypes valType;
public:
Value();
Value(double Val);
Value(int Val);
Value(bool Val);
/* ... */
friend std::ostream& operator <<(std::ostream& stream, const Value& val);
}
我想重載<<
運算符,因此可以打印一個值而無需調查其類型。
這是我目前的實施:
std::ostream &operator <<(std::ostream &os, const Value &val)
{
switch (val.valType)
{
case ValueTypes::Real:
os << val.Real;
break;
case ValueTypes::Integer:
os << val.Integer;
break;
case ValueTypes::Boolean:
os << (val.Boolean ? "True" : "False");
break;
}
return os;
}
首先,在使用g ++(CodeBlocks IDE,Ubuntu)進行編譯時,實現會導致隱式轉換為Value
。 當值類型是Integer
或Real
, os <<
語句將它們轉換為Value
,然后再次調用ostream
重載(無限遞歸),因此我最終得到了分段錯誤。
其次,在使用Visual C ++進行編譯時,隱式轉換已經消失,並且它打印的值很好(不調用隱式構造函數)。
筆記:
我希望保留隱式構造函數,因為它增強了可讀性並簡化了項目其他部分的維護。
另外,我發現了以下博客文章 ,但未能調整我的代碼,因此它將按照我的意願執行(模板的使用有點超出了我目前對cpp語法的理解)。
如何在特定的ostream
重載功能中禁用隱式轉換?
編輯:啟用-Wall
我在CodeBlocks中沒有警告。
你需要#include <ostream>
。 它沒有它的原因是因為它是實際定義std::ostream
的頭部以及所有那些有用的operator<<
函數。
之所以沒有嚇到並抱怨“沒有定義std::ostream
”(或其他<<
運營商)是因為前瞻性聲明。 如果轉發聲明類型,則可以將其用作指針或引用(只要您不嘗試進一步訪問它)。 你可以做一些不完整類型的事情 。
你包含的那些其他頭文件可能正向聲明std::ostream
,但從未給出它和所有<<
運算符的完整定義。 至少在你的Ubuntu系統上。 在其他系統上,其他頭可能包含<ostream>
或者至少提供了<ostream>
所做的一些定義。 您的operator<<
可能是編譯器唯一看到的那個(因為您沒有包含<ostream>
),並且因為它是編譯器唯一知道的,所以它試圖將它用於所有內容。
簡而言之,在處理跨平台的東西時,人們應該迂腐地准確包含必要的內容(並且不依賴於其他標題來包含與它們無關的內容)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.