【问题标题】:Template type deduction模板类型扣除
【发布时间】:2016-06-16 20:02:42
【问题描述】:

我在模板参数列表中遇到过几次class = std::enbale_if<condition, type>::type,我知道std::enable_if<B,T>::type 是做什么的,但不确定class = 是做什么的?我的意思是我知道 class type_name = type 但为什么 class = 中没有类型名称?我什么时候使用它?

编辑:这个例子来自here

template <class T, class U, class = typename enable_if
          <is_lvalue_reference<T>::value ? is_lvalue_reference<U>::value : true>::type>
inline T&& forward(U&& u)
{
    return static_cast<T&&>(u);
}

【问题讨论】:

  • 是编译错误,就是这样。除了编译错误,这只是一个未命名的模板参数。
  • 请发布样本,以便我们更直接地解决它
  • 我编辑了问题

标签: c++ type-deduction


【解决方案1】:

这是SFINAE(替换失败不是错误)。下面是两个示例,其中对 struct 和 class 施加了约束,以禁止使用不正确的类型进行实例化。

但不确定 class= 做什么?我的意思是我知道 class type_name = type 但为什么 class= 中没有类型名称?我什么时候用?

这是一个未命名的模板参数类型,你可以给它一个名字但它不是必需的,因为这个参数只在重载resoultion期间使用(删除无效的候选者)。实际上给它一个名字可能会显示警告。

http://coliru.stacked-crooked.com/a/25162a3eb107943f

// Allow only T to be floating type (!! actually static_assert would be preferred here)
template<class T,
         class = typename std::enable_if<std::is_floating_point<T>::value>::type>
struct foo {

};

template <class T,
          class = typename std::enable_if<std::is_integral<T>::value>::type>
bool is_even(T i) {return !bool(i%2);}

int main()
{
  // foo<int> f;  //error
  foo<float> f;   //ok

  //is_even(1.1); //error
  is_even(1); //ok

  return 0;
}

[编辑]

我必须说上面的例子不是最好的,建议使用 static_assert ,因为它可以生成信息丰富的错误消息。 SFINAE 不应用于参数验证,而应用于根据提供的类型选择其他实现。

【讨论】:

    【解决方案2】:

    这是一个未命名的模板类型参数。就像您可以在未使用的函数参数中省略变量名一样,您可以在未引用的模板参数中省略参数名。

    在 std::enable_if&lt;...&gt;::type 的特定情况下,这仅用于 SFINAE 目的。具体来说,如果enable_if中的boolean为false,则模板参数推导失败。

    【讨论】:

      猜你喜欢
      • 2018-02-19
      • 2012-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-17
      • 2015-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多