【问题标题】:merge a group of template specializations合并一组模板特化
【发布时间】:2020-06-21 21:42:27
【问题描述】:

我有 3 个函数模板特化,具有完全相同的代码。我已经尝试了一段时间,但我无法成功地将它们合并到一个模板表达式中。这是一个示例:

template <typename Event>
void aFunction(const Event &anEvent){
    // do nothing for other types
}
template <>
void aFunction(const InsertEvent &anEvent){
    std::cout<<"aFunction"<<std::endl;
}
template <>
void aFunction(const RemoveEvent &anEvent){
    std::cout<<"aFunction"<<std::endl;
}
template <>
void aFunction(const ChangeEvent &anEvent){
    std::cout<<"aFunction"<<std::endl;
}

编辑: 我尝试使用 std::enable_if_t 合并它们,并且我已经能够按如下方式进行:

template <typename Event>
typename std::enable_if_t<
    !std::is_same<Event, InsertEvent>::value &&
    !std::is_same<Event, RemoveEvent>::value &&
    !std::is_same<Event, ChangeEvent>::value>
aFunction(const Event &anEvent){
    // do nothing for other types
}
template <typename Event>
typename std::enable_if_t<
    std::is_same<Event, InsertEvent>::value ||
    std::is_same<Event, RemoveEvent>::value ||
    std::is_same<Event, ChangeEvent>::value>
aFunction(const Event &anEvent){
    std::cout<<"aFunction"<<std::endl;
}

相反,对于更一般的模板案例,是否可以去掉 !std::is_same<..> 行?

【问题讨论】:

  • 你希望它在其他类型上“什么都不做”,但在其他类型的情况下出错?
  • 对其他类型不做任何事情(SFINAE)

标签: c++ c++14 template-meta-programming


【解决方案1】:

这是一种可能的方法:

template <typename Event>
void aFunction(const Event &anEvent, std::false_type){
    // do nothing for other types
}

template <typename Event>
void aFunction(const Event &anEvent, std::true_type){
    std::cout<<"aFunction"<<std::endl;
}

template <typename Event>
void aFunction(const Event &anEvent){
    aFunction(anEvent, std::integral_constant<bool, 
        std::is_same_v<Event, InsertEvent> ||
        std::is_same_v<Event, RemoveEvent> ||
        std::is_same_v<Event, ChangeEvent>>{});
}

Demo

【讨论】:

  • 谢谢,我认为可以有一种更优雅的编译时方法,而不是在运行时调用内部的另一个函数。
  • 调用很可能被内联。在我的演示中,确实如此。
  • 是否可以将 std::true_type 和 false_type 更改为模板参数而不是函数?然后,我们可以保证编译时分辨率。
  • 如果你把它作为模板参数,那么你需要部分特化。但是没有函数模板的部分特化之类的东西——你需要委托给一个帮助类模板。届时您将立即返回转接电话。
  • 从 C++17 开始,您可以使用 if constexpr。但是你规定了C++14,所以不可用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-28
  • 2022-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多