什么是std :: ref在这个函数中有用?

时间:2015-01-26 21:12:14

标签: c++ c++11 c++14

为什么人们更愿意调用std :: ref而不是根本不调用它?

template<class F, class...Ts> F for_each_arg(F f, Ts&&...a) {
  return (void)initializer_list<int>{(ref(f)((Ts&&)a), 0)...}, f;
  // why not return (void)initializer_list<int>{(f((Ts&&)a), 0)...}, f;
}

1 个答案:

答案 0 :(得分:17)

std::reference_wrapper::operator()执行了一些&#34;魔法&#34;在某些情况下,超出直接函数调用的范围。其效果指定为(引用N4296 [refwrap.invoke]):

template <class... ArgTypes>
result_of_t<T&(ArgTypes&&... )>
operator()(ArgTypes&&... args) const;
     

返回:INVOKE(get(), std::forward<ArgTypes>(args)...)。 (20.9.2)

其中get()返回对reference_wrapper包装内容的引用。 INVOKE在20.9.2 [func.require]中描述:

  

如下定义INVOKE(f, t1, t2, ..., tN)

     

(1.1) - (t1.*f)(t2, ..., tN)f是指向类T的成员函数的指针时,t1T类型的对象或对T类型的对象的引用或对从T派生的类型的对象的引用;

     

(1.2) - ((*t1).*f)(t2, ..., tN)f是指向类T的成员函数的指针时,t1不是上一项中描述的类型之一;

     

(1.3) - t1.*fN == 1f是指向类T的成员数据的指针时,t1T类型的对象{1}}或对T类型对象的引用或对T派生类型的对象的引用;

     

(1.4) - (*t1).*fN == 1f是指向类T的成员数据的指针时,t1不是其中一种类型在前一项中描述;

     

(1.5) - f(t1, t2, ..., tN)在所有其他情况下。

调用ref(f)而不是简单f的结果是指向成员函数的指针和指向成员的指针数据可以被称为&#34;&#34;使用适当的对象指针/引用作为参数。例如,

struct A { void foo(); };
struct B : A {};
struct C : B {};
for_each_arg(&A::foo, A{}, B{}, C{}, std::make_unique<A>());

会在fooAB临时对象以及CDEMO)中保留的对象上调用unique_ptr。为什么更喜欢使用ref(f)超过f显然取决于使用for_each_arg的上下文。

相关问题