2017-02-25 78 views
3

我是新使用模板,並想知道我怎麼能做到以下幾點: 我有一個固定點結構,允許定點計算和定義如下:重映射模板參數結構

template<int bits, int offset> 
struct Fixed { 
     int64_t raw; 
     inline Fixed() {} 
     ... 
} 

我倒是想擴大,這樣我可以聲明一個自定義的浮點表示和編譯器翻譯這對正確的固定點的定義。我想這個如下:

template<int totBits, int expBits, int expOffset> 
struct Fixed<exp2(expBits)+totBits-expBits-2,expOffset-totBits+expBits> { 
     inline Fixed() {} 
     inline explicit Fixed(double value) { 
       Quantization function of floating point here 
     } 
}; 

然而,這給我的錯誤: 「模板參數包括模板參數(S)」。

如何重新映射初始模板,以便我可以執行以下操作:fixed::Fixed<8,3,0> foo; 而編譯器將此視爲:fixed::Fixed<11,-3> foo;

我知道,當我一個值分配給foo我將不得不手動quantise它,就好像它被存儲爲浮點:例如foo = fixed::Fixed<8,3,0>(243)這將給富= 240和foo = fixed::Fixed<8,3,0>(244)會給富= 248

+0

你可以試試:'結構修正:修正了公衆的''而不是固定結構' JVApen

+0

@JVApen這讓我再次聲明與3個參數,而不是原來的聲明,只有2個參數模板投訴。 –

+0

@JVApen他需要用3個參數來聲明主模板,使'固定<位,偏移>'對於部分專業化的工作,我相信。 –

回答

0

一種方式做到這一點是使Fixed<bits, offset>Fixed<totBits, expBits, expOffset>一個特例,使用無效值作爲expOffset

// Forward definition. Third parameter defaults to an invalid value for expOffset. 
// Replace default if necessary. 
template<int, int, int = 256> 
struct Fixed; 

// "Main" specialisation. Used when third parameter is an invalid expOffset. 
// Specialises for when third parameter is default. 
template<int bits, int offset> 
struct Fixed<bits, offset, 256> { 
    int64_t raw; 
    inline Fixed() {} 

    // Dummy implementation for example. 
    inline Fixed(int64_t value) : raw(24) { 
     std::cout << "Fixed<" << bits << ", " << offset << ">(" << value << ")\n"; 
    } 
}; 

// Non-specialised implementation, used for any other value of expOffset. 
// Inherits from main specialisation. 
template<int totBits, int expBits, int expOffset> 
struct Fixed : Fixed<static_cast<int>(exp2(expBits))+totBits-expBits-2,expOffset-totBits+expBits> { 
    using MyBase = Fixed<static_cast<int>(exp2(expBits))+totBits-expBits-2,expOffset-totBits+expBits>; 

    // Dummy implementation for example. 
    inline explicit Fixed(double value) : MyBase(42) { 
     std::cout << "Fixed<" << totBits << ", " << expBits << ", " << expOffset << ">(" << value << ")\n"; 
    } 
}; 

這允許實例化第二個變體,從第一個變體的適當實例化繼承,同時使用相同的名稱。

int main() { 
    std::cout << "f1:\n"; 
    Fixed<11, -3> f1(1); 
    std::cout << "\nf2:\n"; 
    Fixed<8,3,0> f2(1.0); 
} 

Output

f1: 
Fixed<11, -3>(1) 

f2: 
Fixed<11, -5>(42) 
Fixed<8, 3, 0>(1) 

注意,這是有效地正常繼承,儘管有基座和派生類是相同的模板的特殊化兩者;因此,使第二個版本成爲一個單獨的類可以更清楚地傳達你的意圖。

+0

我跟隨你的提示,使其成爲第二類,並給第二類toFixed()函數,它會自動返回正確大小的固定類型。謝謝! –

+0

@StevenLauwereins不客氣。賦予它們相同的名稱意味着第三個值是一個可選的配置值,例如'Fixed <8, 3, 0>'只是一個'Fixed',其中'bits'爲'8','offset'爲'3',但是對第三個參數不使用默認行爲;這可能會使任何不關注其實施的人感到困惑,因此建議。存在這樣的情況是這樣的既可以是有用的,明確的,不過,我相信。 –