4

我对 boost::ref 的使用感到困惑。我不明白为什么有人会想做以下事情 -

void f(int x)
{
    cout << x<<endl;
    x++;
}

int main(int argc, char *argv[])
{
    int aaa=2;
    f(boost::ref(aaa));
    cout << aaa<<endl;
    exit(0);
}

将 ref 传递给函数有什么用。我总是可以按值传递。也不是实际上通过了 ref。在上面的 main 中 aaa 的值仅保持为 2。

boost ref 到底在哪里有用?

在这种情况下是否可以使用 boost::ref 。我想将迭代器引用传递给 std::sort 函数。通常排序适用于迭代器副本- boost::ref 是否也适用于引用?(对 std::sort 没有任何更改)

4

2 回答 2

16

我不明白为什么有人会想做以下事情

他们不会。这不是boost::ref(或这些天std::ref)的目的。如果一个函数通过值接受一个参数,那么就没有办法强制它通过引用来接受它。

boost ref 到底在哪里有用?

它可用于使函数模板表现得好像它通过引用接受参数一样,通过为引用(包装器)类型而不是值类型实例化模板:

template <typename T>
void f(T x) {++x;}

f(aaa);      cout << aaa << endl; // increments a copy: prints 0
f(ref(aaa)); cout << aaa << endl; // increments "a" itself: prints 1

一个常见的特定用途是将参数绑定到函数:

void f(int & x) {++x;}

int aaa = 0;
auto byval = bind(f, aaa);      // binds a copy
auto byref = bind(f, ref(aaa)); // binds a reference

byval(); cout << aaa << endl;   // increments a copy: prints 0
byref(); cout << aaa << endl;   // increments "a" itself: prints 1

在这种情况下是否可以使用 boost:;ref 。我想将迭代器引用传递给 std::sort 函数。通常排序适用于迭代器副本- boost::ref 是否也适用于引用?

不; 引用包装器不满足迭代器要求,因此您不能在标准算法中使用它。如果可以,那么如果许多算法需要制作迭代器的独立副本(包括大多数sort实现,必须这样做),它们就会出现可怕的错误。

于 2013-05-09T11:51:08.770 回答
-2

你读过文档吗?

它说:

Ref 库是一个小型库,可用于将引用传递给通常会复制其参数的函数模板(算法)。

在您的第一个示例中,void f(int)is 不是函数模板,因此没有效果:boost::reference_wrapper<int>创建了一个匿名临时对象并立即转换回 anint&然后取消引用以将 an 传递int给您的函数。希望编译器会丢弃所有这些废话,因为它没有任何效果。

你说:

...我总是可以按值传递。

这是真的,但他们做不同的事情。通过引用传递:

  • 避免复制,这对于整数可能毫无意义,但对于大型或复制成本高的对象很有用
  • 允许调用者查看被调用函数对其参数做了什么。这不太可能对 有用std::sort,但通常允许输入输出参数可能很有用

可能允许std::sort对迭代器引用采取行动,避免复制(尽管迭代器通常是复制成本低的值类型),但我还没有尝试过。如果您认为它会对您有所帮助,为什么不试试看呢?

于 2013-05-09T11:46:54.717 回答