人送外号徐老坏 2022-09-26 19:48 采纳率: 100%
浏览 23
已结题

关于std::make_pair()使用的问题

关于std::make_pair()使用的问题
代码如下
#include <iostream>
#include <map>

std::map<const std::string, int> mTemp;

void Fnc(const std::string& str, int n)
{
    mTemp.insert(std::make_pair(str, n));
    mTemp.insert(std::make_pair<const std::string, int>(str, n)); //报错
    mTemp.insert(std::make_pair<const std::string, int>(str.c_str(), 2)); //使用常量就不报错
}

int main()
{
    std::string strTemp = "cc";
    Fnc(strTemp, 2);
    
    return 0;
}

为什么在make_pair后添加了<T1,T2>就只能使用常量?
  • 写回答

2条回答 默认 最新

  • _GX_ 2022-09-26 21:48
    关注
    #include <iostream>
    #include <map>
     
    std::map<const std::string, int> mTemp;
    
    // C++11中std::pair模板函数原型是
    // template< class T1, class T2 >
    // std::pair<V1, V2> make_pair( T1&& t, T2&& u );
    // 其中形参类型T1&&和T2&&是universal reference
    // 当进行模板参数类型推导时,universal reference推导规则比较特殊:
    // 当传入实参数是左值时,形参类型和模板参数都是左值引用类型
    // 否则的话,形参类型是右值引用
    
    void Fnc(const std::string& str, int n)
    {
        // 这里str和n都是左值(即可以取地址)
    
        // 因此编译器从下面表达式自动推导出:
        // 形参类型T1&& -> const std::string&
        // 形参类型T2&& -> int&
        // 模板参数类型T1 -> const std::string&
        // 模板参数类型T2 -> int&
        // 即std::make_pair函数类型是
        // std::make_pair<const std::string&, int&>(const std::string&, int&)
        mTemp.insert(std::make_pair(str, n));
    
        // 而下面表达式中,模板参数类型已经给定,因此编译不会自动推导
        // std::make_pair函数原型变成
        // std::make_pair<const std::string, int>(const std::string&&, int&&)
        // 注意此时形参类型是右值引用&&
        // 而str和n都是左值,右值引用不能直接绑定左值,因此编译器报错。
        // 其实可以通过std::move()把左值转换为右值引用,比如下面这样就不会报错了
        // mTemp.insert(std::make_pair<const std::string, int>(std::move(str), std::move(n)));
        mTemp.insert(std::make_pair<const std::string, int>(str, n)); //报错
    
        // 这里std::make_pair的函数原型同上
        // str.c_str()返回结果和2都是右值
        // 实际调用的是
        // mTemp.insert(std::make_pair<const std::string, int>(std::string(str.c_str()), 2))
        mTemp.insert(std::make_pair<const std::string, int>(str.c_str(), 2)); //使用常量就不报错
    }
     
    int main()
    {
        std::string strTemp = "cc";
        Fnc(strTemp, 2);
        
        return 0;
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 10月6日
  • 已采纳回答 9月28日
  • 创建了问题 9月26日

悬赏问题

  • ¥15 对于这个复杂问题的解释说明
  • ¥50 三种调度算法报错 有实例
  • ¥15 关于#python#的问题,请各位专家解答!
  • ¥200 询问:python实现大地主题正反算的程序设计,有偿
  • ¥15 smptlib使用465端口发送邮件失败
  • ¥200 总是报错,能帮助用python实现程序实现高斯正反算吗?有偿
  • ¥15 对于squad数据集的基于bert模型的微调
  • ¥15 为什么我运行这个网络会出现以下报错?CRNN神经网络
  • ¥20 steam下载游戏占用内存
  • ¥15 CST保存项目时失败