【问题标题】:What does template<class = enable_if_t<...>> do?template<class = enable_if_t<...>> 做什么?
【发布时间】:2018-09-14 12:31:57
【问题描述】:

我一直在阅读 STL 文件以了解更好的方法来格式化我的代码,并学习提高效率的技巧。我一直在阅读线程文件,但我无法弄清楚某些代码的作用。

template<class _Fn,
    class... _Args,
    class = enable_if_t<!is_same<decay_t<_Fn>, thread>::value>>
    explicit thread(_Fn&& _Fx, _Args&&... _Ax)
    {   // construct with _Fx(_Ax...)
    ...
    }

std::enable_if_t

template<bool _Test,
    class _Ty = void>
    using enable_if_t = typename enable_if<_Test, _Ty>::type;

template<class _Ty>
    struct enable_if<true, _Ty>
    {   // type is _Ty for _Test
    using type = _Ty;
    };

该代码在线程和 str1common STL 中均受版权保护。

我唯一的问题是class = enable_if_t&lt;...&gt; 是做什么的?

【问题讨论】:

标签: c++ stl c++14 variadic-templates sfinae


【解决方案1】:

查找 S.F.I.N.A.E.:“替换失败不是错误”。

查看std::enable_if 的可能实现(std::enable_if_t 只是一个助手using,C++14 引入,以更简单的方式访问type

template<bool B, class T = void>
struct enable_if {};

template<class T>
struct enable_if<true, T> { typedef T type; };

如此iff(当且仅当)模板布尔值(第一个模板参数)为truestd::enable_if&lt;...&gt;::type 已定义(使用第二个模板参数中的类型; void 如果未表达)。

为了简单起见,在你的例子中你有这个

template<class _Fn,
    class... _Args,
    class = enable_if_t<!is_same<decay_t<_Fn>, thread>::value>>
    explicit thread(_Fn&& _Fx, _Args&&... _Ax)
    {   // construct with _Fx(_Ax...)
    ...
    }

enable_if_t(如果第一个值 (!std::is_same&lt;typename std::decay&lt;_Fn&gt;::type, thread&gt;::value) 为 true,则 typename std::enable_if&lt;...&gt;::type) 可用。

即:

  • 如果!std::is_same&lt;typename std::decay&lt;_Fn&gt;::type, thread&gt;::valuetrue,则替换class = enable_if_t&lt;!is_same&lt;decay_t&lt;_Fn&gt;, thread&gt;::value&gt;&gt;并实现函数

  • 如果 !std::is_same&lt;typename std::decay&lt;_Fn&gt;::type, thread&gt;::valuefalse,则替换 class = enable_if_t&lt;!is_same&lt;decay_t&lt;_Fn&gt;, thread&gt;::value&gt;&gt; 失败,该函数未实现这不是错误 (SFINAE)。

为什么语言允许这样做?

因为,举例来说,你可以实现两个版本的函数

template<class _Fn,
    class... _Args, //  vvvv true case
    class = enable_if_t<true == is_same<decay_t<_Fn>, thread>::value>>
    explicit thread(_Fn&& _Fx, _Args&&... _Ax)
    { /* do something */ }

template<class _Fn,
    class... _Args, //  vvvvv false case
    class = enable_if_t<false == is_same<decay_t<_Fn>, thread>::value>>
    explicit thread(_Fn&& _Fx, _Args&&... _Ax)
    { /* do something else */ }

建议:搜索SFINAE学习一下,因为它是现代C++的重要组成部分。

【讨论】:

  • 非常感谢。这就是我认为它正在做的事情,但我真的找不到任何东西来支持这个想法。 SFINAE 正是我希望了解更多的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-08
  • 1970-01-01
  • 2013-11-13
  • 1970-01-01
相关资源
最近更新 更多