【问题标题】:Template parameters SFINAE not using a template argument模板参数 SFINAE 不使用模板参数
【发布时间】:2019-07-12 23:40:26
【问题描述】:

为什么在 C++ 中不允许这样的构造:

#include <type_traits>

template<std::enable_if_t<true, bool> = true>
void fn() {}

template<std::enable_if_t<false, bool> = true>
void fn() {}

int main()
{
    fn();
    return 0;
}

编译器似乎在抱怨enable_if 缺少我相信的模板参数这一事实?有没有办法在不引入另一个模板参数设置为某些默认值的情况下实现上述行为?

【问题讨论】:

  • 您可能简化了一点。声明永远不能使用的东西是没有意义的。
  • 没有S就不是SFINAE!
  • @aschepler 我明白这一点,我只是好奇如何编译上述或类似的东西,如果有的话。
  • @0x499602D2 公平点。我仍然希望实现类似于部分专业化的行为,假设第二个根本不是定义的专业化。

标签: c++ templates c++17 enable-if non-type


【解决方案1】:

需要有一个模板参数来替换,以便 SFINAE 发生。因此,创建一个虚拟模板参数和一个虚拟特征,它将接受它并分别返回 true 和 false。

template<class T>
constexpr bool always_true = true;
template<class T>
constexpr bool always_false = false;

template<class T=void, std::enable_if_t<always_true<T>>* = nullptr>
void fn() {}

template<class T=void, std::enable_if_t<always_false<T>>* = nullptr>
void fn() {}

【讨论】:

  • 无法摆脱我假设的T?
  • @lightxbulb 是的,只需定义一个名为 fn 的函数即可。但是如果你想使用 SFINAE,就没有办法避免这种情况。
  • 我不是特别想用 SFINAE 而是偏函数特化,可惜 C++ 不支持这个。
  • 您可以定义fn 的两个重载(void fn(std::true_type) {} 和void fn(std::false_type) = delete)。它使用重载而不是专业化。如果您仍然想要两个功能,我认为这是您能做的最好的事情。你称它为fn(std::true_type{}); fn(std::false_type{})。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-15
  • 1970-01-01
  • 1970-01-01
  • 2017-10-06
  • 1970-01-01
相关资源
最近更新 更多