在C ++中,std::pair<const T, const U>
和const std::pair<T, U>
之间的行为有何不同?
答案 0 :(得分:13)
核心区别在于它们是不同的不相关类型(其中包含一些隐式转换)。
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)
编译,但该行涉及转换,转换涉及制作{{1>的副本 }}秒。另一方面,调用longstring()
仅在类型匹配时绑定对现有对的常量引用,不需要任何副本。
编译器允许您编写类似代码的事实并不意味着代码被编译为执行相同的操作。对于具有隐式转换的类型尤其如此,例如f(cp)
当编写仿函数来操作存储在地图中的元素时,这是一个常见的陷阱,其中仿函数参数的不匹配将导致不必要的对象数据复制:
std::pair
上面的lambda没有正确的参数类型(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 << " ";
});
与std::pair<int,std::string
)并导致每次调用都复制索引和值(即所有字符串都将被复制,一个std::pair<const int,std::string>
,然后是一个参数绑定到lambda的参数)。在这种情况下,简单的建议是使用std::pair<int,std::string>
作为参数类型。
答案 1 :(得分: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;
}