如何在std::vector中同时存储int与std::string类型元素?
可行的C++实现方案
1. 使用std::variant(C++17及以上)
这是C++标准库原生提供的类型安全变体类型,专门用于存储一组预定义类型中的某一个,完全匹配你需要在容器中存储int和std::string的需求。
示例代码:
#include <vector> #include <variant> #include <string> #include <iostream> int main() { std::vector<std::variant<int, std::string>> container; // 插入不同类型元素 container.emplace_back(123); container.emplace_back("hello world"); // 方式1:手动判断类型并处理 for (const auto& elem : container) { if (std::holds_alternative<int>(elem)) { std::cout << "整数: " << std::get<int>(elem) << std::endl; } else if (std::holds_alternative<std::string>(elem)) { std::cout << "字符串: " << std::get<std::string>(elem) << std::endl; } } // 方式2:用std::visit统一处理(更优雅) auto process_elem = [](const auto& val) { using T = std::decay_t<decltype(val)>; if constexpr (std::is_same_v<T, int>) { std::cout << "访问整数: " << val << std::endl; } else if constexpr (std::is_same_v<T, std::string>) { std::cout << "访问字符串: " << val << std::endl; } }; for (const auto& elem : container) { std::visit(process_elem, elem); } return 0; }
优点:
- 编译期类型检查,完全避免手动维护类型标记的繁琐和错误
- 直接复用标准库组件,无需自定义结构体
std::visit支持统一的类型处理逻辑,比手动判断更简洁优雅
2. 使用std::any(C++17及以上)
如果未来可能需要扩展支持更多类型,std::any可以存储任意类型的值,但需要手动进行类型转换,灵活性更强但安全性稍弱(转换失败会抛出异常)。
示例代码:
#include <vector> #include <any> #include <string> #include <iostream> int main() { std::vector<std::any> container; container.emplace_back(456); container.emplace_back("test string"); for (const auto& elem : container) { if (elem.type() == typeid(int)) { std::cout << "整数: " << std::any_cast<int>(elem) << std::endl; } else if (elem.type() == typeid(std::string)) { std::cout << "字符串: " << std::any_cast<const std::string&>(elem) << std::endl; } } return 0; }
优点:支持任意类型存储,扩展性强
缺点:类型信息仅在运行期可用,编译期无法检查类型匹配;类型转换失败会抛出std::bad_any_cast异常,需额外处理。
3. 多态基类方案(兼容C++11及以上)
如果使用的C版本低于C17,可以定义一个抽象基类,派生出int和std::string的具体子类,用std::vector<std::unique_ptr<Base>>存储指针。注意:该方案存储的是指针而非元素本身,不满足“连续存储元素对象”的严格要求。
示例代码:
#include <vector> #include <memory> #include <string> #include <iostream> class Base { public: virtual ~Base() = default; virtual void print() const = 0; }; class IntValue : public Base { public: int val; IntValue(int v) : val(v) {} void print() const override { std::cout << "整数: " << val << std::endl; } }; class StringValue : public Base { public: std::string val; StringValue(const std::string& v) : val(v) {} void print() const override { std::cout << "字符串: " << val << std::endl; } }; int main() { std::vector<std::unique_ptr<Base>> container; container.emplace_back(std::make_unique<IntValue>(789)); container.emplace_back(std::make_unique<StringValue>("polymorphism test")); for (const auto& ptr : container) { ptr->print(); } return 0; }
优点:兼容C++11及以上版本;面向对象的设计让类型处理逻辑更清晰
缺点:容器存储指针,不满足连续存储元素本身的需求;需通过智能指针管理内存(避免泄漏)
内容的提问来源于stack exchange,提问作者roulette01
相关产品推荐
相关产品推荐

