gpt4 book ai didi

c++ - 特殊模板功能

转载 作者:太空宇宙 更新时间:2023-11-04 14:12:49 25 4
gpt4 key购买 nike

考虑以下模板来存储简化的 SI 单位:

template < int Mass, int Length, int Time >
class TUnit
{
public:
// Used type.
typedef float DataType;
.....
}

例如 SI 单位“长度”定义如下:

typedef TUnit< 0, 1, 0 > Length;

有一个全局通用函数将 DataTypes 转换为 TUnits:

template < int Mass, int Length, int Time >
TUnit< Mass, Length, Time > convert( const typename TUnit< Mass, Length, Time >::DataType& src );

我们有一个专门的版本可以将 float 转换为长度,例如隐式转换,例如从 [km] 到 [m]:

template < >
Tools::DataTypes::Length convert( const Tools::DataTypes::Length::DataType& src );

现在尝试将 float 转换为长度:

float f = 1.0;
Length l = ::convert( f )

现在VC2012编译失败,错误代码:

error C2783: could not deduce template argument for 'Mass'
could not deduce template argument for 'Length'
could not deduce template argument for 'Time'

为了解决这个问题,我将代码更改为:

float f = 1.0;
Length l = ::convert< 0, 1, 0 >( f )

不错,但这不是我想要的 :) 我首选的语法是:

float f = 1.0;
Length l = ::convert< Length >( f )

我认为我必须将通用模板函数的签名更改为如下所示:

template < TUnit< int Mass, int Length, int Time > >
TUnit< Mass, Length, Time > convert( const typename TUnit< Mass, Length, Time >::DataType& src );

但是当然这个语法是错误的。有什么解决这个问题的提示吗?

最佳答案

1。变体(通过模板类)

您不能特化函数模板。如果你真的想这样做,那么创建一个具有单个静态函数的类并专门化该类。然后,您可以使该函数调用该类的静态方法。

template < int Mass, int Length, int Time >
TUnit< Mass, Length, Time > convert( const typename TUnit< Mass, Length, Time >::DataType& src ) {
return Converter<Mass, Length, Time>::call();
}

然后定义模板类:

template < int Mass, int Length, int Time >
struct Converter {
static TUnit< Mass, Length, Time > call( const typename TUnit< Mass, Length, Time >::DataType& src) {
[...]
}
};

及其专业,例如长度:

template < >
struct Converter<0,1,0> {
static const int Mass = 0;
static const int Length = 1;
static const int Time = 0;

static TUnit< Mass, Length, Time > call( const typename TUnit< Mass, Length, Time >::DataType& src) {
[...]
}
};

2。变体重载

或者,我建议改用函数重载,这在很大程度上是等效的,我的意思是

// NOTE: no `template < >`
Tools::DataTypes::Length convert( const Tools::DataTypes::Length::DataType& src );

由于 C++ 重载机制,此重载函数优先于函数模板 convert<Mass, Length, Time> .只要您不使用显式模板参数调用该函数即可。

3。变体附加功能模板

如果您想使用第二种方法工作,那么我建议:

template < int Mass_, int Length_, int Time_ >
class TUnit
{
public:
static const int Mass = Mass_;
static const int Length = Length_;
static const int Time = Time_;
[...]

然后

template < class TUnitT >
TUnitT convert( const typename TUnitT::DataType& src ) {
return convert<TUnitT::Mass, TUnitT::Length, TUnitT::Time>(src);
}

但我会推荐第一种方法。

关于c++ - 特殊模板功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13349407/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com