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

std::unordered_map::emplace返回类型显式声明错误,求正确写法

模板类中std::unordered_map::emplace返回值的显式类型声明问题

问题代码

#include <iostream>
#include <unordered_map>

template<class T>
class MSet {
public:
    std::unordered_map<T, int> map;
    MSet(): map(std::unordered_map<T, int>()) {};
    void add(T e);
};

template<class T>
void MSet<T>::add(T e) {
    std::pair<std::unordered_map<T, int>::iterator, bool> ret = map.emplace(e, 1);
    if (ret.second) {
        std::cout << "Added" << std::endl;
    }
}

int main(int, char**){
    MSet<int> mset;
    mset.add(1);
}

编译错误信息

[build] /home/experiment/main.cpp: In member function ‘void MSet<T>::add(T)’:
[build] /home/experiment/main.cpp:14:57: error: type/value mismatch at argument 1 in template parameter list for ‘template<class _T1, class _T2> struct std::pair’
[build]      std::pair<std::unordered_map<T, int>::iterator, bool> ret = map.emplace(e, 1);
[build]                                                          ^
[build] /home/experiment/main.cpp:14:57: note:   expected a type, got ‘std::unordered_map<T, int>::iterator’
[build] /home/experiment/main.cpp:15:13: error: request for member ‘second’ in ‘ret’, which is of non-class type ‘int’
[build]      if (ret.second) {
[build]              ^~~~~~
[build] /home/experiment/main.cpp: In instantiation of ‘void MSet<T>::add(T) [with T = int]’:
[build] /home/experiment/main.cpp:23:15:   required from here
[build] /home/experiment/main.cpp:14:59: error: cannot convert ‘std::pair<std::__detail::_Node_iterator<std::pair<const int, int>, false, false>, bool>’ to ‘int’ in initialization
[build]      std::pair<std::unordered_map<T, int>::iterator, bool> ret = map.emplace(e, 1);
[build]                                                            ^~~

解决方案

问题原因

在模板类的成员函数中,std::unordered_map<T, int>::iterator是依赖于模板参数T的类型,编译器在模板实例化前无法确定它是一个类型还是静态成员变量/常量,因此必须用typename关键字显式告知编译器这是一个类型。

正确的显式类型声明写法

直接修改类型声明,添加typename关键字:

template<class T>
void MSet<T>::add(T e) {
    typename std::pair<typename std::unordered_map<T, int>::iterator, bool> ret = map.emplace(e, 1);
    if (ret.second) {
        std::cout << "Added" << std::endl;
    }
}

更清晰的写法(推荐)

通过using定义类型别名,提升代码可读性:

template<class T>
void MSet<T>::add(T e) {
    using MapType = std::unordered_map<T, int>;
    using EmplaceResult = typename std::pair<typename MapType::iterator, bool>;
    EmplaceResult ret = map.emplace(e, 1);
    
    if (ret.second) {
        std::cout << "Added" << std::endl;
    }
}

当然,auto是最简洁的方式,编译器会自动推导正确的返回类型,这也是C++11及以后推荐的写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 09:53:25