You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改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;
}

关键改动说明:

  1. 用std::variant替代双数组:std::variant<Types...>可以存储指定的多种类型(这里是double和char),类型安全,不会出现内存混乱。
  2. 用std::vector管理存储:vector自动处理动态扩容和内存释放,不用手动写new/delete,避免内存泄漏。
  3. 模板简化:用可变模板参数typename... Types,让栈支持任意多种指定类型,而不是固定两种。
  4. 修正push/pop逻辑:push直接向vector尾部添加元素,pop移除尾部元素,完美符合LIFO规则。
  5. 用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 12:32:50