我想请教您关于功能模板的建议。我有一个功能,可以将一些数据添加到缓冲区。但我还需要将有关数据类型的信息添加到缓冲区中。数据类型是以下枚举:
enum ParameterType
{
UINT,
FLOAT,
DOUBLE
};
我需要从这样的函数创建一个函数模板:
void SomeBuffer::append( double par )
{
appendType( DOUBLE );
memcpy( pStr + _length, &par, sizeof( double ) );
_length += sizeof( double );
appendType( DOUBLE );
}
请您告诉我如何根据参数类型从ParameterType传递appendType()的值。
template<class T>
void SomeBuffer::append( T par )
{
appendType( ??? );
memcpy( pStr + _length, &par, sizeof( T ) );
_length += sizeof( T );
appendType( ??? );
}
我尝试通过一些宏来做,但没有成功。非常感谢您的任何建议。
答案 0 :(得分:7)
您可以通过引入一个额外的类模板来执行您想要的操作,该模板将类型映射到您需要的枚举常量,如以下示例所示(为简洁起见,不使用FLOAT):
enum ParameterType
{
UINT,
DOUBLE
};
template <typename T>
struct GetTypeCode;
template <>
struct GetTypeCode<double>
{
static const ParameterType Value = DOUBLE;
};
template <>
struct GetTypeCode<unsigned>
{
static const ParameterType Value = UINT;
};
template <typename T>
void SomeBuffer::append(T par)
{
appendType(GetTypeCode<T>::Value);
memcpy(pStr + _length, &par, sizeof(T));
_length += sizeof(T);
appendType(GetTypeCode<T>::Value);
}
由于GetTypeCode的特化几乎相同,因此您可以引入一个用于定义它们的宏,例如
#define MAP_TYPE_CODE(Type, ID) \
template <> \
struct GetTypeCode<Type> \
{ \
static const ParameterType Value = ID; \
};
MAP_TYPE_CODE(double, DOUBLE)
MAP_TYPE_CODE(unsigned, UINT)
答案 1 :(得分:4)
template <typename T> struct identity { };
inline void appendType_(identity<double> ) { appendType(DOUBLE); }
inline void appendType_(identity<unsigned>) { appendType(UINT); }
inline void appendType_(identity<MyType> ) { appendType(MY_TYPE); }
然后像这样使用它:
template<class T>
void SomeBuffer::append( T par )
{
appendType_( identity<T>() );
memcpy( pStr + _length, &par, sizeof( T ) );
_length += sizeof( T );
appendType_( identity<T>() );
}
您还可以将此与@ vitaut单独获取类型代码并将其传递给appendType
的想法结合起来。
inline ParameterType typeCode(identity<double> ) { return DOUBLE; }
inline ParameterType typeCode(identity<unsigned>) { return UINT; }
inline ParameterType typeCode(identity<MyType> ) { return MY_TYPE; }
...
appendType(typeCode(identity<T>()));
编辑:感谢@Johannes提出的identity<T>
建议。
答案 2 :(得分:2)
Marcelo Cantos给出的另一种方法是创建一个元函数:
template <typename T>
struct my_type_id; // undefined as to trigger compiler error for unknown types
template <>
struct my_type_id<double> {
static const ParameterType value = DOUBLE;
};
template <>
struct my_type_id<float> {
static const ParameterType value = float;
};
然后使用它来解析枚举值:
template<class T>
void SomeBuffer::append( T par )
{
appendType( my_type_id<T>::value );
memcpy( pStr + _length, &par, sizeof( T ) );
_length += sizeof( T );
appendType( my_type_id<T>::value );
}
可以在宏中定义特征的实际定义:
#define TYPE_ID_MAP( type, val ) \
template <> struct my_type_id<type> { \
const static ParameterType value = val;\
}
template <typename T>
struct my_type_id; // undefined as to trigger compiler error for unknown types
TYPE_ID_MAP( double, DOUBLE );
TYPE_ID_MAP( float, FLOAT );
TYPE_ID_MAP( unsigned int, UINT );