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

基于initializer_list构造支持多态与内联构造的非const值map

没问题,咱们来实现一个完全符合你所有要求的map。核心是用智能指针来存储多态对象——直接存类对象会触发切片问题,而智能指针既能保留多态特性,又能自动管理内存,完美匹配你的需求。

先上完整代码示例:

#include <iostream>
#include <map>
#include <memory>

struct foo { virtual void print() { std::cout << "foo"; } };
struct bar : foo { virtual void print() { std::cout << "bar"; } };

int main() {
    // 直接用initializer_list构造目标map
    std::map<int, std::unique_ptr<foo>> my_map = {
        {1, std::make_unique<foo>()},
        {2, std::make_unique<bar>()}
    };

    // 验证多态性和非const特性
    for (auto& entry : my_map) {
        entry.second->print(); // 多态调用:1输出foo,2输出bar
        // 如果foo有非const成员函数,比如void setVal(int),也能直接调用:
        // entry.second->setVal(42);
        std::cout << "\n";
    }

    // 完全不需要手动清理内存,unique_ptr会自动处理
    return 0;
}

接下来逐个对应你的要求,看看怎么满足:

  • 值具备多态性:用std::unique_ptr<foo>作为map的值类型,指针可以指向foo或它的派生类bar,调用虚函数print()时会自动触发对应类的实现,完美保留多态行为。
  • 值为非const类型:std::unique_ptr<foo>指向的是非const对象,你可以自由调用对象的非const成员函数(如果有的话),完全符合要求。
  • 通过initializer_list构造:直接用{ {1, make_unique<foo>()}, {2, make_unique<bar>()} }初始化列表构造map,没有额外的转换步骤。
  • 在initializer_list内部构造值:每个std::make_unique<foo>()和std::make_unique<bar>()都是在初始化列表内部直接构造出对应的对象,并包装成智能指针,所有构造逻辑都在列表里完成。
  • 无需辅助函数、lambda或宏:全程只用了标准库的std::map、std::unique_ptr和std::make_unique,没有任何自定义的辅助工具。
  • 不需要单独清理函数:std::unique_ptr会在map销毁(比如离开main函数作用域)时自动释放所指向的对象,完全不需要手动delete或者专门的清理逻辑。

如果你的环境是C11(std::make_unique是C14引入的),可以把初始化列表里的make_unique换成直接构造unique_ptr,效果完全一样:

// C++11兼容版本的初始化方式
std::map<int, std::unique_ptr<foo>> my_map = {
    {1, std::unique_ptr<foo>(new foo())},
    {2, std::unique_ptr<foo>(new bar())}
};

内容的提问来源于stack exchange,提问作者Jonathan Mee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:20:21