c++ - 如何测试是否存在模板函数特化

标签 c++ templates c++11 c++14 template-meta-programming

我正在管理单位转换。告诉我们,我达到了我实现这一目标的状态。

我在不同单位之间转换的核心在于以下通用模板函数:

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; }

Live Demo

关于c++ - 如何测试是否存在模板函数特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38637674/

相关文章:

c++ - 为什么 is_copy_assignable 的实现不起作用?

C++11 std::condition_variable:我们可以将锁直接传递给通知线程吗?

c++ - C++错误,编译器无法识别字符串::push_back [closed]

c++ - 如果子类没有非静态成员或析构函数,我是否需要虚拟析构函数?

c++ - 如果参数是 uint64 类型,则 Ffs 不会返回正确的结果

C++整数类型自动64位

c++ - 我正在尝试从 GMocked 类返回一个 rapidjson::Value 但我似乎无法让它工作

c++ - 在 C++ 中,是否可以消除数组引用和指针之间的歧义?

c++ - 删除 CPropertySheet/Tabbed Dialog 页面下方的间隙

c++ - 不同编译器使用的不同类型转换运算符