如何在STL容器内传递和操作常量(或非常量)引用。说我有一个功能:
bool foo(const Obj& A, const Obj& B) {
// do some computation on A & B
}
并且自A& B总是一起出现,我想把它们放在STL对中:
bool foo(const std::pair<Obj, Obj>& A_and_B) {
// do some computation on A & B
}
然而现在两个对象A&amp;每次需要调用foo时,B都会被复制到一对中。环顾四周,我在C ++ 11中找到了reference_wrapper。虽然做这样的事情并不是很有效:
bool foo(const std::pair<std::reference_wrapper<Obj>, std::reference_wrapper<Obj>>& A_and_B) {
// do some computation on A & B
}
bool foo(const std::pair<Obj, Obj>& A_and_B) {
foo(std::make_pair(std::ref(A_and_B.first), std::ref(A_and_B.second)));
}
在不使用指针的情况下使用引用值传递容器的正确方法是什么?
答案 0 :(得分:1)
为了避免在make_pair时复制,为什么不直接将对定义为std::pair<Obj&, Obj&>
?
#include <iostream>
#include <string>
#include <functional>
class Obj
{
};
bool foo(const std::pair<Obj, Obj>& A_and_B) {
// do some computation on A & B
std::cout << __func__ << std::endl;
}
bool foo(const std::pair<Obj&, Obj&>& A_and_B) {
// do some computation on A & B
std::cout << "ref version foo" << std::endl;
}
int main( void )
{
Obj A;
Obj B;
foo( std::make_pair(std::ref(A), std::ref(B)) );
return 0;
}
答案 1 :(得分:1)
这是一种方式,只传递一对引用(不复制):
#include <utility> // pair
#include <functional> // ref
#include <iostream>
using namespace std;
struct Obj {};
auto foo( pair<Obj const&, Obj const&> const ab )
{
Obj const& a = ab.first;
Obj const& b = ab.second;
cout << &a << " " << &b << endl;
}
auto main() -> int
{
Obj a;
Obj b;
cout << &a << " " << &b << endl;
foo( make_pair( ref( a ), ref( b ) ) );
}
这很好用,因为std::make_pair
对std::reference_wrapper
参数有特殊支持,然后推断对引用类型的引用。
std::reference_wrapper
是std::ref
的结果类型。
答案 2 :(得分:0)
由于std::make_pair
支持移动语义,您只需按照建议编写函数,但在调用它时将对象A
和B
移入std::make_pair
如下所示:
// Just as you already suggested
bool foo(const std::pair<Obj, Obj>& A_and_B) {
// do some computation on A & B
}
将其命名为:
int main( void )
{
Obj A; // work on A
Obj B; // work on B
auto A_and_B = std::make_pair(std::move(A), std::move(B)); // effectively moves A and B; no copies!
// A and B are now reset, but you can use A_and_B.first and A_and_B.second!
foo( A_and_B );
return 0;
}
答案 3 :(得分:-1)
由于您通过引用传递对,因此不会复制它。但是,Obj A=A_and_B.first
将创建副本。如果你想避免这种情况,你可以获得对元素的引用,即
Obj &A=A_and_B.first
。