常量对和常量对之间的区别

Difference between pair of consts and const pair

本文关键字:常量 区别 之间      更新时间:2023-10-16

在C++中,std::pair<const T, const U>const std::pair<T, U>之间的行为有什么区别?

核心区别在于它们是不同的不相关类型(它们之间有一些隐式转换)。

void f(std::pair<std::string,std::string> const &);
std::string longstring();
int main() {
   std::pair<const std::string,const std::string> pc
        = std::make_pair(longstring(),longstring());
   f(pc);
   const std::pair<std::string,std::string> cp
        = std::make_pair(longstring(),longstring());
   f(cp); 
}

虽然存在允许f(pc)编译的隐式转换,但该行涉及转换,转换涉及创建longstring()的副本。另一方面,调用f(cp)仅在类型匹配时绑定对现有对的常量引用,不需要任何副本。

编译器让你编写类似的代码这一事实并不意味着代码被编译为做同样的事情。对于具有隐式转换的类型尤其如此,例如std::pair

这是编写函子以对存储在映射中的元素进行操作时常见的陷阱,其中函子参数的不匹配将导致不必要的对象数据复制:

std::map<int,std::string> m = create_map();
std::for_each(m.begin(),m.end(),
              [](std::pair<int,std::string> const &r) { 
                    std::cout << r.second << " ";
              });

上面的 lambda 没有正确的参数类型(std::pair<int,std::string vs. std::pair<const int,std::string> ),这会导致每次调用将索引和值都复制到 std::pair<int,std::string>,然后将参数绑定到 lambda 的引用)。在这种情况下,简单的建议是将std::map<int,std::string>::value_type const &用于参数类型。

从我所做的测试来看,行为是相同的。

#include <utility>
int main() {
   std::pair<const int, const int> p = std::make_pair(2,3);
   p = std::make_pair(3, 4); // error
   p.first = 5; // also error
   const std::pair<int, int> p2 = std::make_pair(4,5);
   p2 = std::make_pair(4, 5); // error
   p2.first = 0; // error
   return 0;
}