2017-02-25 74 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',但是对第三个参数不使用默认行为;这可能会使任何不关注其实施的人感到困惑,因此建议。存在这样的情况是这样的既可以是有用的,明确的,不过,我相信。 –