跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C++17 stdany
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
{{DISPLAYTITLE:C++17 <code>std::any</code>}} '''<code>std::any</code>''' 是 C++17 标准引入的一个类型安全的容器,用于存储任意类型的单个值。它类似于动态类型语言中的变量,可以在运行时存储和检索不同类型的值,同时保持类型安全。与 <code>void*</code> 不同,<code>std::any</code> 会跟踪存储的类型信息,并在错误的类型访问时抛出异常。 == 基本介绍 == <code>std::any</code> 是 <code><any></code> 头文件中定义的类模板,它提供了一种灵活的方式来存储和操作不同类型的值。主要特点包括: * '''类型安全''':在访问存储的值时,会检查类型是否匹配。 * '''动态存储''':可以存储任何可复制构造的类型(包括基本类型、类、指针等)。 * '''异常处理''':如果尝试以错误的类型访问值,会抛出 <code>std::bad_any_cast</code> 异常。 == 基本用法 == 以下示例展示了 <code>std::any</code> 的基本操作: <syntaxhighlight lang="cpp"> #include <any> #include <iostream> #include <string> int main() { std::any data; // 存储一个整数 data = 42; std::cout << "Stored int: " << std::any_cast<int>(data) << '\n'; // 存储一个字符串 data = std::string("Hello, C++17!"); std::cout << "Stored string: " << std::any_cast<std::string>(data) << '\n'; // 检查是否有值 if (data.has_value()) { std::cout << "Data has a value.\n"; } // 尝试错误类型访问(抛出异常) try { std::cout << std::any_cast<double>(data) << '\n'; } catch (const std::bad_any_cast& e) { std::cout << "Error: " << e.what() << '\n'; } // 重置 any 对象 data.reset(); if (!data.has_value()) { std::cout << "Data is empty.\n"; } } </syntaxhighlight> '''输出:''' <pre> Stored int: 42 Stored string: Hello, C++17! Data has a value. Error: bad any_cast Data is empty. </pre> === 代码解释 === 1. <code>std::any data</code> 创建一个空的 <code>any</code> 对象。 2. <code>data = 42</code> 存储一个整数,<code>std::any_cast<int>(data)</code> 安全地提取该值。 3. <code>data.has_value()</code> 检查是否包含值。 4. <code>std::any_cast<double>(data)</code> 尝试以错误类型访问,抛出异常。 5. <code>data.reset()</code> 清空对象。 == 实际应用场景 == <code>std::any</code> 在需要处理多种类型的场景中非常有用,例如: * '''插件系统''':存储不同插件的配置或状态。 * '''动态配置''':解析 JSON 或 XML 时存储不确定类型的值。 * '''事件处理''':传递不同类型的事件数据。 === 示例:动态配置存储 === <syntaxhighlight lang="cpp"> #include <any> #include <vector> #include <iostream> #include <string> struct Config { std::string name; std::any value; }; int main() { std::vector<Config> settings = { {"timeout", 30}, {"server", std::string("localhost")}, {"debug", true} }; for (const auto& cfg : settings) { std::cout << cfg.name << ": "; if (cfg.value.type() == typeid(int)) { std::cout << std::any_cast<int>(cfg.value); } else if (cfg.value.type() == typeid(std::string)) { std::cout << std::any_cast<std::string>(cfg.value); } else if (cfg.value.type() == typeid(bool)) { std::cout << std::boolalpha << std::any_cast<bool>(cfg.value); } std::cout << '\n'; } } </syntaxhighlight> '''输出:''' <pre> timeout: 30 server: localhost debug: true </pre> == 性能与注意事项 == * <code>std::any</code> 使用小对象优化(Small Object Optimization),小型对象(如基本类型)直接存储,大型对象(如类)在堆上分配。 * 频繁的类型检查或错误访问可能影响性能。 * 避免在性能关键路径中使用 <code>std::any</code>。 == 类型检查与转换 == 可以通过 <code>type()</code> 成员函数获取存储值的类型信息: <syntaxhighlight lang="cpp"> std::any data = 3.14; if (data.type() == typeid(double)) { std::cout << "Data is a double.\n"; } </syntaxhighlight> == 与 <code>std::variant</code> 的比较 == {| class="wikitable" |- ! <code>std::any</code> !! <code>std::variant</code> |- | 存储任意类型 || 存储预先定义的一组类型 |- | 运行时类型检查 || 编译时类型检查 |- | 可能抛出异常 || 通过 <code>std::visit</code> 安全访问 |} == 总结 == <code>std::any</code> 提供了一种灵活且类型安全的方式来处理动态类型数据,适用于需要运行时类型不确定的场景。使用时需注意性能开销和异常处理。 [[Category:编程语言]] [[Category:C++]] [[Category:C++141720 特性]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)