簡體   English   中英

如何在具有不同模板參數的C ++模板之間隱式轉換

[英]How to implicitly cast between C++ templates with different template parameters

我試圖創建一個包裝整數值的C ++模板類,並檢查該值是否始終在有效范圍內,因此簡化的代碼如下:

struct OutOfRangeError  
{ };  

template<int MIN, int MAX, typename TYPE>  
struct IntegerRange  
{  
    private:  
    TYPE mValue;  

    public:  
    IntegerRange(const TYPE value) : mValue(value)  
    {  
        if (MIN > value || value > MAX)  
        {  
            throw OutOfRangeError();  
        }  
    }  

    operator TYPE() const  
    {  
        return mValue;  
    }  
}  

以前的代碼可以工作,但在使用這個類時它有一些缺點。 這是一個示例:

typedef IntegerRange<0, 4, int> range1_t;  
typedef IntegerRange<0, 5, int> range2_t;  

range1_t a = 3;  
//range2_t b = a; // This does not work  
range2_t b = static_cast<int>(a); // This works OK  

因此,要在不同范圍之間分配值,我必須明確地轉換為給定的TYPE。 我想有一個解決方案,以避免這種顯式轉換和處理IntegerRange類,因為它們是正常的整數。 所以開發人員應該感覺他正在處理普通的整數而不是類。

為了解決這個問題,我試了不同的東 一個工作是以下一個作為額外的構造函數:

template<typename RANGE_TYPE>  
IntegerRange(const RANGE_TYPE &value) :  
        mValue(static_cast<const TYPE>(value))  
{  
    if (MIN > mValue || mValue > MAX)  
    {  
        throw OutOfRangeError();  
    }  
}  

但是,即使這樣可行,我也不太喜歡,因為RANGE_TYPE可以是任何能夠轉換為TYPE的類型,我想將此限制為只有IntegerRange類。 要僅將其限制為IntegerRange類,我嘗試了以下但是它沒有編譯,我不明白原因:

template<int ARG_MIN, int ARG_MAX, typename ARG_TYPE>  
IntegerRange(const IntegerRange<ARG_MIN, ARG_MAX, typename ARG_TYPE> &value) :  
        mValue(static_cast<const TYPE>(value))  
{  
    if (MIN > value || value > MAX)  
    {  
        throw OutOfRangeError();  
    }  
}  

問題是2:
*為什么最后一段代碼沒有編譯,我需要更改以編譯它。
*有沒有更好的避免我遺漏的明確演員?

謝謝

首先, 您不應該使用ARG_MAX作為模板名稱,因為它可能已經被定義為POSIX數字常量。

其次,您應該刪除IntegerRange的第三個模板參數中的typename

IntegerRange(const IntegerRange<ARG_MIN, ARG_MAX, ARG_TYPE> &value) :

也許您應該將valueARG_TYPE ,它將直接調用您的operator ARG_TYPE() ,然后讓編譯器從ARG_TYPE轉換為TYPE而不是轉換為TYPE並讓編譯器推斷從ARG_TYPE可能的轉換和對operator ARG_TYPE()的調用。 使用第一種解決方案,有關不可能轉換的編譯錯誤可能更明確。

RANGE_TYPE可以是任何能夠轉換為TYPE的類型,我想將其限制為只有IntegerRange類。 僅限於IntegerRange

只需交換模板參數的順序並聲明為

template<typename TYPE, TYPE2 MIN, TYPE2 MAX>  
struct IntegerRange

這將起作用,因為模板參數推導不會隱式轉換arg類型。 例如float到int。



//range2_t b = a; // This does not work  

當然。 ab有不同的類型。 請記住,對於每個模板專業化,都會創建該類的新模板。 您不能分配兩個對象,因為它們的類型看起來相似。

class A { int a; }; class B { int a; };
A a; B b; a = b;  // Should not work

為了做a = b你需要提供可以從另一個IntegerRange構造IntegerRange復制構造函數。 (這里不需要賦值,因為你有類型轉換運算符。)

template<typename TYPE2, TYPE MIN2, TYPE MAX2>
IntegerRange(const IntegerRange<TYPE2,MIN2,MAX2>& ot) {
    if (MIN > ot.mValue || ot.mValue > MAX)  
    {  
        throw OutOfRangeError();  
    }  

    mValue = ot.mValue;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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