folly学习(五):std::void_t中存在的bug

folly学习(五):std::void_t中存在的bug标准库中std::void_t的实现如下:void_t主要是在模板偏特化中使用,但这一实现,在libstdc++、libc++和MSVC的STL

大家好,欢迎来到IT知识分享网。folly学习(五):std::void_t中存在的bug"

标准库中std::void_t的实现如下:

template<typename...> 
 using void_t = void;

void_t主要是在模板偏特化中使用,但这一实现,在libstdc++、libc++和MSVC的STL中是存在bug的,这个bug导致它忽略了模板别名中未使用的模板参数,有时候并没有引起替换失败。这个bug已被记录在:

http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1558

例如:

struct A {
    using one = int;
};

struct B {
    using two = float;
};

template <typename T,
          std::void_t<typename std::decay_t<T>::one>* = nullptr>
void foo(T&&) { }

template <typename T,
          std::void_t<typename std::decay_t<T>::two>* = nullptr>
void foo(T&&) { }

int main()
{
    foo(A{}); //  error: redefinition of ‘template<class T, std::void_t<typename std::decay<_Tp>::type::two>* <anonymous> > void foo(T&&)’
}

第二个foo()将被认为是一个重新定义,因为它与第一个冲突;void_t不会导致替换失败–模板类型被忽略。

folly中实现了自己的void_t,用以修复这一bug,位于:

folly/Traits.h

代码分析

改进方式是,用如下实现替换:

namespace traits_detail {
template <class T, class...>
struct type_t_ {
  using type = T;
};
} // namespace traits_detail

template <class T, class... Ts>
using type_t = typename traits_detail::type_t_<T, Ts...>::type;
template <class... Ts>
using void_t = type_t<void, Ts...>;

其中type_t用来获取模板的第一个模板参数。

测试

namespace traits_detail {
template <class T, class...>
struct type_t_ {
  using type = T;
};
} // namespace traits_detail

template <class T, class... Ts>
using type_t = typename traits_detail::type_t_<T, Ts...>::type;
template <class... Ts>
using void_t = type_t<void, Ts...>;

struct A
{
    using one = int;
};

struct B
{
    using two = float;
};

template <typename T,
          void_t<typename std::decay_t<T>::one>* = nullptr>
void
foo(T&&)
{
    std::cout << "one" << std::endl;
}
template <typename T,
          void_t<typename std::decay_t<T>::two>* = nullptr>
void
foo(T&&)
{
    std::cout << "two" << std::endl;
}

int
main()
{
    foo(A{});
    foo(B{});
}

输出:

one
two

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/60688.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信