C++如何在编译时检查模板参数class的签名
C++ how to check the signature of a template parameter class at compile time
在下面的代码中,我试图检查作为第二个模板参数传递给 WTrajectory
的 class 的签名。在当前实现中,WTrajectory
的构造函数比较模板参数 T
的类型和作为第二个参数传递给它的类型的模板参数。
当前的实现可以执行检查。但是,如果可能的话,我更愿意在编译时执行它。此外,我还想检查模板参数 TWPoint
是否具有成员函数 returnTimeTypeID
,也在编译时(可以在此处找到在 运行 时执行此检查的解决方案: link).
template<typename T>
struct WPoint
{
const std::type_info& returnTimeTypeID(void) const
{return typeid(T);}
};
template<typename T, typename TWPoint>
struct WTrajectory
{
WTrajectory(const TWPoint& wp)
{
compare_types(wp);
}
void compare_types(const TWPoint& wp)
{
if (typeid(T) != wp.returnTimeTypeID())
throw std::runtime_error("Error");
}
};
由于 returnTimeTypeID
是非虚拟的,编译器将在编译时知道 TWPoint
的动态类型。因此,与其进行运行时检查,不如更改您的模板:
template<typename T>
struct WTrajectory
{
typedef T TWPoint;
...
在编译时检查模板类型是否具有特定方法的最佳方法是直接调用方法。如果它不提供所需的功能,您将收到编译错误。
如果 WPoint
包含的不仅仅是类型信息,那么下面的代码将起作用
template<typename T>
struct WPoint
{
// ... stuff not related to type checking
};
template<typename T>
struct WTrajectory
{
WTrajectory(const WPoint<T>& wp)
{
}
};
如果 WPoint
除了类型信息之外不包含任何其他内容,您可以将其删除。
在下面的代码中,我试图检查作为第二个模板参数传递给 WTrajectory
的 class 的签名。在当前实现中,WTrajectory
的构造函数比较模板参数 T
的类型和作为第二个参数传递给它的类型的模板参数。
当前的实现可以执行检查。但是,如果可能的话,我更愿意在编译时执行它。此外,我还想检查模板参数 TWPoint
是否具有成员函数 returnTimeTypeID
,也在编译时(可以在此处找到在 运行 时执行此检查的解决方案: link).
template<typename T>
struct WPoint
{
const std::type_info& returnTimeTypeID(void) const
{return typeid(T);}
};
template<typename T, typename TWPoint>
struct WTrajectory
{
WTrajectory(const TWPoint& wp)
{
compare_types(wp);
}
void compare_types(const TWPoint& wp)
{
if (typeid(T) != wp.returnTimeTypeID())
throw std::runtime_error("Error");
}
};
由于 returnTimeTypeID
是非虚拟的,编译器将在编译时知道 TWPoint
的动态类型。因此,与其进行运行时检查,不如更改您的模板:
template<typename T>
struct WTrajectory
{
typedef T TWPoint;
...
在编译时检查模板类型是否具有特定方法的最佳方法是直接调用方法。如果它不提供所需的功能,您将收到编译错误。
如果 WPoint
包含的不仅仅是类型信息,那么下面的代码将起作用
template<typename T>
struct WPoint
{
// ... stuff not related to type checking
};
template<typename T>
struct WTrajectory
{
WTrajectory(const WPoint<T>& wp)
{
}
};
如果 WPoint
除了类型信息之外不包含任何其他内容,您可以将其删除。