何时使用std :: ref是必要的?

时间:2012-08-06 17:30:30

标签: c++ c++11 portability correctness

考虑:

std::tuple<int , const A&> func (const A& a) 
{
  return std::make_tuple( 0 , std::ref(a) );
}

编写正确且可移植的代码需要std::ref吗? (如果没有它,它编译得很好)

背景:

如果删除std::ref我的代码构建正常而没有任何警告(g++-4.6 -Wall),但无法正常运行。

如果感兴趣的话,A的定义:

struct A {
  std::array<int,2> vec;
  typedef int type_t;

  template<typename... OPs,typename... VALs>
  A& operator=(const std::pair< std::tuple<VALs...> , std::tuple<OPs...> >& e) {
    for( int i = 0 ; i < vec.size() ; ++i ) {
      vec[i] = eval( extract(i,e.first) , e.second );
    }
  }
};

3 个答案:

答案 0 :(得分:14)

  • make_tuple(0, a)制作tuple<int, A>
  • make_tuple(0, ref(a))制作tuple<int, reference_wrapper<A>>
  • 您也可以对tuple<int, A&> t(0, a);无法使用的元组说make_tuple,或使用std::tie

答案 1 :(得分:11)

std::ref没有引用,因此在您的代码示例中,它不会按预期执行。 std::ref创建一个行为与引用类似的对象。例如,当您想要实例化仿函数并将其类似引用的版本传递给标准库算法时,它可能很有用。由于算法按值使用仿函数,因此您可以使用std::ref来包装仿函数。

答案 2 :(得分:8)

需要std::ref的示例之一:

void update(int &data)  //expects a reference to int
{
    data = 15;
}
int main()
{
    int data = 10;

    // This doesn't compile as the data value is copied when its reference is expected.
    //std::thread t1(update, data);         

    std::thread t1(update, std::ref(data));  // works

    t1.join();
    return 0;
}

std::thread构造函数复制提供的值,而不转换为预期的参数类型(在本例中为 reference 类型,请参阅update())。所以我们需要在std::ref包装真正需要引用的参数

相关问题