lrl*_*eon 5 c++ templates template-meta-programming c++11 c++14
我正在管理单位转换.告诉我们,我达到了实现这一目标的状态.
我在不同单元之间转换的核心在于以下通用模板函数:
template <class SrcUnit, class TgtUnit> extern
double convert(double val);
Run Code Online (Sandbox Code Playgroud)
该函数的目标是将以类型SrcUnit为单位表示的物理量值转换为以类型为单位表示的另一物理量值TgtUnit.
我有一个叫做Quantity<Unit>管理值及其统一的类,这个类试图给出类型安全和自动转换.例如,我导出以下构造函数:
template <class SrcUnit>
Quantity(const Quantity<SrcUnit> & q)
: unit(UnitName::get_instance())
{
check_physical_units(q); // verify that the physical magnitudes are the same
value = convert<SrcUnit, UnitName>(q.value); // <<- here the conversion is done
check_value(); // check if the value is between the allowed interval
}
Run Code Online (Sandbox Code Playgroud)
我导出转换完成的其他东西.
因此,当有人希望管理新单元时,她会指定一个新的Unit派生类.我通过在宏中放入新类的所有必需规范来实现这一点.现在,该用户有责任编写转换函数.那就是编写convert()模板的两个特化.例如,假设您有一个名为'Kilometer and you wish to specify a new unit calledMile` 的单位.在这种情况下,您执行此操作:
Declare_Unit(Mile, "mi", "English unit of length", Distance,
0, numeric_limits<double>::max()); // macro instantiating a new Unit class
template <> double convert<Kilometer, Mile>(double val) { return val/1609.344; }
template <> double convert<Mile, Kilometer>(double val) { return 1609.344*val; }
Run Code Online (Sandbox Code Playgroud)
现在,如果用户忘记编写转换函数会发生什么?那么,在这种情况下,链接器将失败,因为它无法找到特化convert().
虽然我认为链接器错误是可接受的,因为向用户报告缺失的行为convert(),我想测试我编译convert()专业化存在的时间.所以我的问题是如何实现这一目标?我想static_assert在每次调用之前通过一个put来convert()判断专业化是否已经知道.但是怎么做呢?
PS:另外,如果有人能推荐我关于C++元编程的好文本,对我来说非常有用.
您可以通过static_assert在主函数模板中放置一个小技巧来做到这一点,这将确保您的程序不会格式错误,不会从这里无耻地窃取:
template <typename...> struct always_false : std::false_type {};
template<typename T, typename U> double convert(double) {
static_assert(always_false<T, U>::value, "No specialization exists!");
}
template <> double convert<Kilometer, Mile>(double val) { return val/1609.344; }
template <> double convert<Mile, Kilometer>(double val) { return 1609.344*val; }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1005 次 |
| 最近记录: |