结构体是否包含特定类型的成员变量

news/2024/11/14 15:45:23/

结构体是否包含特定类型的成员变量

在C++中,可以使用模板元编程和类型特性(type traits)来判断一个结构体是否包含特定类型的成员变量。这通常通过std::is_member_object_pointer类型特性来实现,它可以用来检查给定的成员指针是否指向结构体中的成员。

#include <iostream>
#include <type_traits>struct S1 {int id = 0;
};struct S2 {int id = 0;std::string code;
};// 检查T类型是否包含名为'code'的std::string类型成员变量
template <typename T, typename = void>
struct has_code : std::false_type {};template <typename T>
struct has_code<T, std::void_t<decltype(T::code)>> : std::is_same<decltype(T::code), std::string> {};// 辅助变量模板
#if _HAS_CXX17
template <typename T>
inline constexpr bool has_code_v = has_code<T>::value;
#else
template <typename T>
constexpr bool has_code_v = has_code<T>::value;
#endifint main() {std::cout << std::boolalpha;std::cout << "S1 has code: "<< has_code_v<S1> << std::endl; // 输出: falsestd::cout << "S2 has code: " << has_code_v<S2> << std::endl; // 输出: truereturn 0;
}

在这个示例中:

  1. has_code是一个模板结构体,它使用SFINAE(Substitution Failure Is Not An Error)技术来检查类型T是否包含名为code的成员变量。
  2. std::void_t<decltype(T::code)>用于在T类型中存在名为code的成员时产生一个void类型,否则产生一个替换失败。
  3. std::is_same<decltype(T::code), std::string>用于检查code成员是否为std::string类型。
  4. has_code_v是一个变量模板,它提供了一个方便的方式来直接访问has_code<T>::value的值。
  5. has_code 模板结构体的定义
  • 主模板 template<typename T, typename = void> struct has_code : std::false_type {};:这是一个通用的模板定义,当没有针对特定类型 T 的特化版本被匹配时,它将被使用。这里默认继承自 std::false_type,表示假设类型 T 不包含名为 codestd::string 类型成员变量。
  • 特化模板 template<typename T> struct has_code<T, std::void_t<decltype(T::code)>> : std::is_same<decltype(T::code), std::string> {};:这个特化版本仅在 T 中存在名为 code 的成员变量时才会被匹配。
  • std::void_t<decltype(T::code)> 是一个巧妙的技巧,它使用 decltype(T::code) 来获取 Tcode 成员的类型,如果 T 中不存在 code 成员,decltype(T::code) 会导致替换失败(这是 C++ 模板替换失败不是错误原则的应用),从而这个特化版本不会被匹配,而是使用主模板。如果 T 中存在 code 成员,std::void_t<decltype(T::code)> 会被替换为 void,特化版本就会被匹配,然后通过 std::is_same<decltype(T::code), std::string> 来进一步检查 code 成员的类型是否为 std::string

这种方法可以扩展到检查任何类型的成员变量,只需将std::string替换为你需要检查的类型即可。


http://www.ppmy.cn/news/1546962.html

相关文章

PHP开发示例-vin码识别接口-引领汽车行业数字化新风向

在当今社会&#xff0c;随着互联网技术的飞速发展&#xff0c;各行各业都在经历着深刻的变革&#xff0c;汽车行业也不例外。从智能驾驶到车联网&#xff0c;技术创新不断推动着汽车行业的进步。在这一背景下&#xff0c;VIN码识别技术作为连接线上与线下、传统与现代的桥梁&am…

Android 开启流量节省状态会使热点与网络共享无法打开

流量节省&#xff08;Data saver&#xff09;默认状态&#xff1a; vendor/mediatek/proprietary/packages/apps/SettingsProvider/res/values/defaults.xml <bool name"def_restrict_background_data">true</bool> 如果为true&#xff0c;WLAN热点无…

数据库SQLite的使用

SQLite是一个C语言库&#xff0c;实现了一个小型、快速、独立、高可靠性、功能齐全的SQL数据库引擎。SQLite文件格式稳定、跨平台且向后兼容。SQLite源代码属于公共领域(public-domain)&#xff0c;任何人都可以免费将其用于任何目的。源码地址&#xff1a;https://github.com/…

WPF+MVVM案例实战与特效(二十八)- 自定义WPF ComboBox样式:打造个性化下拉菜单

文章目录 1. 引言案例效果3. ComboBox 基础4. 自定义 ComboBox 样式4.1 定义 ComboBox 样式4.2 定义 ComboBoxItem 样式4.3 定义 ToggleButton 样式4.4 定义 Popup 样式5. 示例代码6. 结论1. 引言 在WPF应用程序中,ComboBox控件是一个常用的输入控件,用于从多个选项中选择一…

新的服务器Centos7.6 安装基础的环境配置(新服务器可直接粘贴使用配置)

常见的基础服务器配置之Centos命令 正常来说都是安装一个docker基本上很多问题都可以解决了&#xff0c;我基本上都是通过docker去管理一些容器如&#xff1a;mysql、redis、mongoDB等之类的镜像&#xff0c;还有一些中间件如kafka。下面就安装一个 docker 和 nginx 的相关配置…

企业级工位管理:Spring Boot解决方案

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理企业级工位管理系统的相关信息成为必然。开…

『OpenCV-Python』视频的读取和保存

点赞 + 关注 + 收藏 = 学会了 推荐关注 《OpenCV-Python专栏》 上一讲介绍了 OpenCV 的读取图片的方法,这一讲简单聊聊 OpenCV 读取和保存视频。 视频的来源主要有2种,一种是本地视频文件,另一种是实时视频流,比如手机和电脑的摄像头。 要读取这两种视频的方法都是一样的…

效率工具-tig的使用

1、tig的安装 apt-get install tig 或者 brew install tig2、常用指令 2.1 tig 进入tig界面 在git 的repository 输入tig 进入tig界面 2.2 【 r 】进入 refs view 模式&#xff0c;查看所有分支&#xff0c;使用 【 j/k 】上下切换&#xff0c; 【 Enter 】查看分支演化 2.2…