模板<class>&gt;是什么做?

时间:2018-04-04 20:10:17

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

我一直在阅读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<...>做了什么?

1 个答案:

答案 0 :(得分:4)

寻找S.F.I.N.A.E。:&#34;替换失败不是错误&#34;。

查看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 (当且仅当)模板布尔值(第一个模板参数)为true时,定义了std::enable_if<...>::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(如果第一个值(typename std::enable_if<...>::type))为!std::is_same<typename std::decay<_Fn>::type, thread>::value,则true可用。

那是:

  • 如果!std::is_same<typename std::decay<_Fn>::type, thread>::valuetrue,则执行替换class = enable_if_t<!is_same<decay_t<_Fn>, thread>::value>>并实施该功能

  • 如果!std::is_same<typename std::decay<_Fn>::type, thread>::valuefalse,则替换class = enable_if_t<!is_same<decay_t<_Fn>, thread>::value>>失败,该功能未实现,但此问题已解决错误(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 ++的重要组成部分。