簡體   English   中英

選擇性隱式轉換

[英]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 當值類型是IntegerRealos <<語句將它們轉換為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM