【问题标题】:What's the point of "boost::mpl::identity<T>::type" here?这里的“boost::mpl::identity<T>::type”有什么意义?
【发布时间】:2015-01-09 04:52:07
【问题描述】:

我正在检查 clamp 在 boost 中的实现:

  template<typename T, typename Pred> 
  T const & clamp ( T const& val, 
    typename boost::mpl::identity<T>::type const & lo, 
    typename boost::mpl::identity<T>::type const & hi, Pred p )
  {
//    assert ( !p ( hi, lo ));    // Can't assert p ( lo, hi ) b/c they might be equal
    return p ( val, lo ) ? lo : p ( hi, val ) ? hi : val;
  } 

如果我查看文档,identity 会返回未更改的模板参数。

身份元功能。返回 X 不变。

那么在这里使用它有什么意义呢?

typename boost::mpl::identity&lt;T&gt;::type不等于T吗?

【问题讨论】:

  • 禁用对这些参数的类型推断
  • 所以它纯粹根据第一个参数扣除T?啊……谢谢
  • 是的,正如你所说的

标签: c++ templates boost template-argument-deduction


【解决方案1】:

nested-name-specifier 创建了一个非推导上下文。因此,编译器不会尝试根据声明为的第二个和第三个参数推断类型T

typename boost::mpl::identity<T>::type const &

类型T将仅根据第一个参数的类型推导,然后用于实例化其余参数的类型。使用identity 类型是防止某些参数的模板参数类型推导的常用技巧,否则在参数类型不同但使用相同类型模板参数的情况下会导致模棱两可的调用错误。有时也可能希望不让编译器自动推断类型,并强制调用者自己进行。

【讨论】:

  • 还有其他方法可以达到同样的效果吗? (除了我想写另一个函数并投射lohi
  • @Barry 毫无疑问,因为有类似的方法可以创建不可演绎的上下文。然而,很少有人会像这样优雅和惯用。那么,你为什么要以其他方式呢? (如果你不喜欢 MPL,就自己写 identity 元函数吧。全部是~6行代码)
  • +1 吹毛求疵:您可能想提一下,在非推导上下文中使用嵌套的::type 允许在hilo 上进行隐式转换,这在参数推导过程中不予考虑.允许这种混合参数类型将是这里的主要应用。
  • @sehe 只是好奇。 MPL 没有问题。尽管如此,为什么 template &lt;typename T&gt; using alias = T 不能算作非推断上下文?
  • @Barry 因为只是别名,没有实例化
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-28
  • 1970-01-01
  • 1970-01-01
  • 2013-01-01
  • 1970-01-01
相关资源
最近更新 更多