【发布时间】:2016-12-02 22:09:05
【问题描述】:
我正在管理单位转换。告诉我们,我达到了我实现这一目标的状态。
我在不同单位之间转换的核心在于以下通用模板函数:
template <class SrcUnit, class TgtUnit> extern
double convert(double val);
此函数的目标是以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
}
我导出完成转换的其他内容。
因此,当有人希望管理一个新单元时,她指定一个新的Unit 派生类。我通过将新类的所有所需规范放入宏中来实现这一点。现在,这个用户有责任编写转换函数。也就是写convert()模板的两个特化。例如,假设您有一个名为“Kilometerand 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; }
现在,如果用户忘记编写转换函数会怎样?好吧,在这种情况下,链接器将失败,因为它找不到 convert() 特化。
现在是我的问题。
虽然我认为链接器错误作为向用户报告缺少的convert() 的行为是可以接受的,但我想测试我的编译时间是否存在convert() 专业化。所以我的问题是我怎么能做到这一点?我猜想通过在每次调用convert() 之前放置static_assert 来测试专业化是否已知。但是该怎么做呢?
PS:另外,如果有人能向我推荐一篇关于 C++ 元编程的好文章,那对我来说非常有用。
【问题讨论】:
-
检查link。有作者正在使用元编程机器开发一个单位转换系统。总的来说,最好的 TMP 介绍恕我直言。
-
这似乎是一个根本上糟糕的设计。所以你有
N^2转换功能?您必须分别实现 bothKilometer到Mile和Mile到Kilometer吗? -
如果物理学允许
N^2转换,那么是的@Barry。对于第二个问题,也是。请注意,有些情况下转换不是严格线性的;尽管这听起来很奇怪,但对于某些地质相关性来说就是这种情况,其中转换只能在经验有效的区间内有效。包容性,在某些情况下,只允许在一次意义上进行转换。无论如何,非常欢迎任何关于设计的建议 -
我所说的
N^2的意思是,如果你有N单位,那么每个单位都需要自己的转换函数到每个其他单位......所以你有N^2不同的转换函数。那...不能很好地扩展。 -
好的@Barry 我明白了。是的,这不能很好地扩展,但我相信没有逃脱。我检查过的其他一些系统使用矩阵转换,虽然它可能更简洁,但仍然是二次的。在我目前工作的领域中,经验公式和不同单位的使用令人印象深刻。问候
标签: c++ templates c++11 c++14 template-meta-programming