第三方SDK定义了几种类型定义,如:如何为同一类型的typedefs提供模板特化?
typedef unsigned char SDK_BYTE
typedef double SDK_DOUBLE
typedef unsigned char SDK_BOOLEAN
它还定义了变量类型SdkVariant:
class SdkVariant
{
public:
enum SdkType { SdkByte, SdkDouble, SdkBoolean };
bool toByte(SDK_BYTE&);
bool toDouble(SDK_DOUBLE&);
bool toBool(SDK_BOOLEAN&);
SdkType type();
};
检索从这种变型的值看起来像这样(假定,我们知道所含值的类型):
SdkVariant variant(foobar());
double value;
bool res = variant.toDouble(value);
if (!res)
diePainfully();
else
doSomethingWith(value);
这是相当冗长,因此我想要提供一个variant_cast功能级是c一个执行值检索和错误处理:
// general interface:
template<class T>
class variant_cast
{
public:
T operator()(const SdkVariant& variant);
};
// template specializations:
template<>
SDK_DOUBLE variant_cast<SDK_DOUBLE>::operator()(const SdkVariant& variant)
{
SDK_DOUBLE value;
bool res = variant.toDouble(value);
if (!res)
diePainfully();
return value;
}
template<>
SDK_BYTE variant_cast<SDK_BYTE>::operator()(const SdkVariant& variant)
{
SDK_BYTE value;
bool res = variant.toByte(value);
if (!res)
diePainfully();
return value;
}
template<>
SDK_BOOLEAN variant_cast<SDK_BOOLEAN>::operator()(const SdkVariant& variant)
{
SDK_BOOLEAN value;
bool res = variant.toByte(value);
if (!res)
diePainfully();
return value;
}
这并不编译(C2995:已定义功能模板),因为SDK_BYTE和SDK_BOOLEAN是相同的类型(无符号字符)。我的想法是让预处理器检查SDK_BYTE和SDK_BOOLEAN是否相同,如果是这样,请为两者定义单个模板专用化。如果它们不同,它应该使用上面两个独立的专业化。像这样:
#if SDK_BYTE == SDK_BOOLEAN
template<>
SDK_BYTE variant_cast<SDK_BYTE>::operator()(const SdkVariant& variant)
{
SDK_BYTE value;
bool res;
if (variant.type() == SdkByte)
res = variant.toByte(value);
else
res = variant.toBool(value);
if (!res)
diePainfully();
return value;
}
#else
// code from above
#endif
上述代码的问题是,预处理器似乎无法解析两个typedefs。有没有办法在预处理过程中比较两个typedef(正确)?如果没有,是否有办法阻止编译器解析类型定义,以便为SDK_BYTE和SDK_BOOLEAN接受两个不同的模板专门化?如果不是,我仍然可以提供单个模板专门化,并且如果SDK_BYTE和SDK_BOOLEAN不相等,则使用BOOST_STATIC_ASSERT使编译器失败,但有没有更好的方法来解决我的问题?
不幸的是,预处理器不理解'typedefs'。 – 2012-08-16 06:53:19
['BOOST_STRONG_TYPEDEF'](http://www.boost.org/doc/libs/1_50_0/boost/strong_typedef.hpp) – Xeo 2012-08-16 07:16:31
您可以使用C++ 11和'std :: enable_if',并结合'std: :is_same'? – jogojapan 2012-08-16 07:34:08