如何修改C++模板栈代码,实现多类型元素存入单一数组并支持LIFO
解决混合类型栈的实现问题
你的代码目前的核心问题是:用两个独立数组分别存储不同类型的元素,还共用一个top变量,这本质上是两个并行的栈,完全没法实现单一栈的LIFO(后进先出)逻辑。而且pop函数的参数完全没有用到,pushT2类型时还错误地输出了sptr1的内容,这些都是需要修正的点。
要实现能存储不同类型的单一栈,C++17及以上版本最适合的方案是用std::variant——它可以安全地存储多种指定类型的对象,且不需要手动管理内存。下面是修改后的完整代码:
#include <iostream> #include <vector> #include <variant> #include <functional> // 模板栈,支持存储指定的多种类型 template<typename... Types> class MultiTypeStack { private: // 用vector存储variant,自动管理动态扩容,不用手动new/delete数组 std::vector<std::variant<Types...>> elements; public: // 判断栈是否为空 bool empty() const { return elements.empty(); } // 获取栈的大小 size_t size() const { return elements.size(); } // 压入任意指定类型的元素 template<typename T> void push(const T& obj) { elements.push_back(obj); // 可选:压入后打印当前栈内容 std::cout << "Push后栈内容: "; printAll(); std::cout << std::endl; } // 弹出栈顶元素(无返回值,若需要返回可以加返回逻辑) void pop() { if (!empty()) { elements.pop_back(); // 可选:弹出后打印当前栈内容 std::cout << "Pop后栈内容: "; printAll(); std::cout << std::endl; } else { std::cerr << "栈为空,无法执行pop操作!" << std::endl; } } // 打印栈顶元素 void printTop() const { if (!empty()) { const auto& topElem = elements.back(); std::cout << "栈顶元素: "; // 用std::visit访问variant中的具体类型 std::visit([](const auto& val) { std::cout << val; }, topElem); std::cout << std::endl; } else { std::cerr << "栈为空,无栈顶元素!" << std::endl; } } // 打印所有元素(从栈底到栈顶) void printAll() const { for (const auto& elem : elements) { std::visit([](const auto& val) { std::cout << val << " "; }, elem); } } }; int main() { // 实例化一个支持double和char类型的栈 MultiTypeStack<double, char> s; s.push('a'); s.push(5.5); s.push(7.77); s.push('*'); s.push(11.01); s.push('?'); std::cout << "\n当前栈大小: " << s.size() << std::endl; s.printTop(); s.pop(); s.printTop(); s.pop(); s.pop(); s.printAll(); return 0; }
关键改动说明:
- 用
std::variant替代双数组:std::variant<Types...>可以存储指定的多种类型(这里是double和char),类型安全,不会出现内存混乱。 - 用
std::vector管理存储:vector自动处理动态扩容和内存释放,不用手动写new/delete,避免内存泄漏。 - 模板简化:用可变模板参数
typename... Types,让栈支持任意多种指定类型,而不是固定两种。 - 修正
push/pop逻辑:push直接向vector尾部添加元素,pop移除尾部元素,完美符合LIFO规则。 - 用
std::visit处理类型访问:因为variant存储的是多种类型,需要用std::visit来安全地访问内部的具体值,实现打印等操作。
代码运行示例输出:
Push后栈内容: a Push后栈内容: a 5.5 Push后栈内容: a 5.5 7.77 Push后栈内容: a 5.5 7.77 * Push后栈内容: a 5.5 7.77 * 11.01 Push后栈内容: a 5.5 7.77 * 11.01 ? 当前栈大小: 6 栈顶元素: ? Pop后栈内容: a 5.5 7.77 * 11.01 栈顶元素: 11.01 Pop后栈内容: a 5.5 7.77 * Pop后栈内容: a 5.5 7.77 a 5.5 7.77
兼容性说明:
如果你的编译器不支持C++17,可以考虑用基类+多态的方案:定义一个基类StackElement,然后让每个类型的元素继承它,栈里存储std::unique_ptr<StackElement>,但这种方式需要手动实现每个类型的子类,代码量更大,不如std::variant简洁。
内容的提问来源于stack exchange,提问作者Libra2019
相关产品推荐
相关产品推荐

