在SQL Server 11中将reference_wrapper对象作为函数参数传递

时间:2016-05-24 00:28:36

标签: c++ c++11 stl

如何在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)));
}

在不使用指针的情况下使用引用值传递容器的正确方法是什么?

4 个答案:

答案 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_pairstd::reference_wrapper参数有特殊支持,然后推断对引用类型的引用。

std::reference_wrapperstd::ref的结果类型。

答案 2 :(得分:0)

由于std::make_pair支持移动语义,您只需按照建议编写函数,但在调用它时对象AB移入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;
}

Live demo.

答案 3 :(得分:-1)

由于您通过引用传递对,因此不会复制它。但是,Obj A=A_and_B.first将创建副本。如果你想避免这种情况,你可以获得对元素的引用,即

Obj &A=A_and_B.first