C++17一个很冷门很有意思的新特性

2022-07-01 14:11:52 浏览数 (1)

最近发现了一个有意思的特性:void_t。

void_t是C 17引入的一个新特性,它的定义很简单(有些编译器的实现可能不是这样,但也大体类似):

代码语言:javascript复制
template< class... >using void_t = void;

看着它很简单,但它搭配SFINAE却可以在模板元编程中发挥巨大作用。

比如在编译期判断类是否有某个类型using:

代码语言:javascript复制
template <class, class = std::void_t<>>struct has_type : std::false_type {};
template <class T>struct has_type<T, std::void_t<typename T::type>> : std::true_type {};

比如判断是否有某个成员:

代码语言:javascript复制
template <class, class = std::void_t<>>struct has_a_member : std::false_type {};
template <class T>struct has_a_member<T, std::void_t<decltype(std::declval<T>().a)>> : std::true_type {};

比如判断某个类是否可迭代:

代码语言:javascript复制
template <typename, typename = void>constexpr bool is_iterable{};
template <typename T>constexpr bool is_iterable<T, std::void_t<decltype(std::declval<T>().begin()), decltype(std::declval<T>().end())>> = true;

比如判断某个类是否有某个函数:

代码语言:javascript复制
template <class T, class = void>struct has_hello_func : std::false_type {};
template <class T>struct has_hello_func<T, std::void_t<decltype(std::declval<T>().hello())>> : std::true_type {};

测试结果:

代码语言:javascript复制
struct HasType {  typedef int type;};struct NHasType {  int hello;};
struct Hasa {  int a;};struct NHasa {  int b;};
struct HasHello {  void hello();};struct NoHasHello {};
int main() {  std::cout << has_type<HasType>::value << 'n';   // 1  std::cout << has_type<NHasType>::value << 'n';  // 0
  std::cout << has_a_member<Hasa>::value << 'n';   // 1  std::cout << has_a_member<NHasa>::value << 'n';  // 0
  std::cout << has_hello_func<HasHello>::value << 'n';    // 1  std::cout << has_hello_func<NoHasHello>::value << 'n';  // 0
  std::cout << is_iterable<std::vector<double>> << 'n';  // 1  std::cout << is_iterable<double> << 'n';               // 0}

它的原理其实就是利用SFINAE和模板优先找特化去匹配的特性,估计大家应该看示例代码就能明白。

推荐阅读

  • 内推字节 Linux C/C 开发的那位同学没通过面试......
  • 那些做客户端 C/C 开发的同学,现在怎么样了?
  • 你的简历中不要写这些信息哦!
  • HR 开价 20K,如何谈到 27K?
  • 哈哈哈,发年终奖啦,我要去斗鱼打赏最喜欢的妹子~
  • 大厂,那高高的围墙
  • 来看一看两道大厂面试场景题
  • 大厂伤我千百遍,我待大厂如初恋
  • 给工作 4 年迷茫的程序员们的一点建议
  • 『腾讯后台开发』实习生技能要求
  • 写给学历不好但想毕业开个好头的你
  • 他山之玉——五一假期进大厂直播分享活动通知
  • 大一大二的计算机专业同学应该学习什么?如何学习?
  • Java 为什么不采用 360 垃圾清理来进行垃圾回收呢?
  • 如果一定要在 C 和 Java 中选择,是选 C 还是 Java ?
  • C 面试应该准备哪些技能点?分别能达到什么薪资水平?
  • C 游戏服务器开发有什么推荐的学习资料或者书籍?
  • 你一定要搞明白的 C 函数调用方式与栈原理
  • Modern C 智能指针详解
  • Modern C ,学炸了!!
  • C 代码优化应该怎么学?
  • 有哪些不错的 Golang 开源项目?
  • 定位后端开发,有哪些书籍值得推荐?
  • 我们说 TCP 是流式协议究竟意味着什么?
  • 一个 WebSocket 服务器是如何开发出来的?
  • 从零实现一个 http 服务器
  • 使用 epoll 时需要将 socket 设为非阻塞吗?
  • Linux 的 epoll 使用 LT 非阻塞 IO 和 ET 非阻塞 IO 有效率上的区别吗?
  • 在 2021 年写一本 C 图书是一种什么体验?
  • 《C 服务器开发精髓》签名版请签收
  • 小方说服务器开发:一个实实在在帮你提高后端开发能力的优质圈子!
代码语言:javascript复制
如果想加入 高质量 C   微信交流群 进行交流,可以先加我微信 easy_coder,备注"加微信群",我拉你入群,备注不对不加哦

如有收获,点个在看,诚挚感谢

0 人点赞