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

C++新手求助:模板类指针作为std::unordered_map键编译报错

解决模板类中std::unordered_map相关编译错误及逻辑问题

问题分析与修复步骤

  • 静态成员未定义:模板类的静态成员attachCaches仅在类内声明,必须在类外提供定义,否则编译器会报未定义符号错误。
  • std::unordered_map的insert方法使用错误:datas.insert(key, properties)不符合unordered_map的接口规范,insert需要传入std::pair类型参数,或使用emplace直接构造键值对。
  • 返回值导致逻辑失效:原attach函数返回对象副本,调用set仅修改副本,缓存内的原对象不会更新,最终get会因找不到键抛出异常,需改为返回引用。
  • 注:指针作为std::unordered_map的键时,标准库已提供默认哈希函数,无需额外自定义。

修正后的完整代码

#include <iostream>
#include <utility>
#include <unordered_map>
#include <string>

template<typename T,typename EX>
class Attachable
{
    static std::unordered_map<T*, Attachable<T,EX>> attachCaches;

    std::unordered_map<std::string, EX> datas;
    T* m_attachedObj;

    // 私有构造函数,仅通过attach创建实例
    Attachable(T* sender): m_attachedObj(sender) {}

public:
    // 返回引用,确保修改直接作用于缓存内的对象
    static Attachable<T,EX>& attach(T* sender)
    {
        auto it = attachCaches.find(sender);
        if(it == attachCaches.end())
        {
            // 使用emplace直接构造,避免不必要的拷贝
            it = attachCaches.emplace(sender, Attachable<T,EX>(sender)).first;
        }
        return it->second;
    }

    void set(const std::string& key, const EX& properties)
    {
        // 用emplace高效插入键值对,也可替换为insert(std::make_pair(key, properties))
        datas.emplace(key, properties);
    }

    EX get(const std::string& key)
    {
        return datas.at(key);
    }
};

// 模板静态成员的类外定义,必须提供
template<typename T, typename EX>
std::unordered_map<T*, Attachable<T,EX>> Attachable<T,EX>::attachCaches;

class Tester
{
public:
    Tester() = default;
};

int main()
{
    Tester* a = new Tester();
    Attachable<Tester, std::string>::attach(a).set("test", "typeOfInt");
    std::cout << Attachable<Tester, std::string>::attach(a).get("test") << std::endl;

    // 测试int指针场景
    int* b = new int(4);
    Attachable<int, std::string>::attach(b).set("num", "four");
    std::cout << Attachable<int, std::string>::attach(b).get("num") << std::endl;

    // 释放内存(示例中建议添加)
    delete a;
    delete b;
    return 0;
}

关键修改说明

  • 补充模板静态成员attachCaches的类外定义,解决编译阶段未定义符号错误。
  • 将attach函数返回值改为引用类型,确保set操作直接修改缓存内的对象。
  • 修正datas的插入逻辑,用emplace符合unordered_map的接口要求。
  • 移除不必要的operator==,因为attachCaches的键是T*,无需比较Attachable对象本身。

内容的提问来源于stack exchange,提问作者xiangyue qiu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 18:57:54