19

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

4

2 回答 2

16

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

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)编译的隐式转换,但该行涉及一个转换,并且该转换涉及制作s的副本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::stringvs. std::pair<const int,std::string>),这会导致每次调用都复制索引和值(即,所有字符串都将被复制到 an std::pair<int,std::string>,然后将引用绑定到 lambda 的参数) . 在这种情况下,简单的建议是使用std::map<int,std::string>::value_type const &参数类型。

于 2013-01-31T17:21:49.850 回答
0

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

#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;
}
于 2013-01-31T16:57:50.870 回答