我正在管理单位转换。告诉我们,我达到了我实现这一目标的状态。
我在不同单位之间转换的核心在于以下通用模板函数:
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()
模板。例如,假设您有一个名为“公里 and you wish to specify a new unit called
”的单位英里`。在这种情况下,您可以这样做:
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()
特化。所以我的问题是我怎样才能做到这一点?我想通过 static_assert
在每次调用 convert()
之前放置它测试特化是否已知。但是该怎么做呢?
PS:另外,如果有人能给我推荐一本关于 C++ 元编程的好书,那将对我非常有用。
最佳答案
你可以通过在主函数模板中放置一个 static_assert
来做到这一点,并使用一个小技巧来确保你的程序不是错误的,从 here 无耻地偷来的:
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; }
关于c++ - 如何测试是否存在模板函数特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38637674/