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

Mar*_*tin 10 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;
}
Run Code Online (Sandbox Code Playgroud)

Cas*_*sey 17

std::reference_wrapper::operator()在某些情况下,执行一些"魔法"超出直接函数调用.其效果指定为(引用N4296 [refwrap.invoke]):

template <class... ArgTypes>
result_of_t<T&(ArgTypes&&... )>
operator()(ArgTypes&&... args) const;
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

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

(1.4) - (*t1).*fwhen N == 1f是指向类的成员数据的指针,T并且t1不是前一项中描述的类型之一;

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

调用ref(f)而不是简单的结果f是指针到成员函数和指向成员数据的指针可以用适当的对象指针/引用作为参数"调用".例如,

struct A { void foo(); };
struct B : A {};
struct C : B {};
for_each_arg(&A::foo, A{}, B{}, C{}, std::make_unique<A>());
Run Code Online (Sandbox Code Playgroud)

会叫fooA,BC临时对象,并在举行的对象unique_ptr(DEMO).为什么人们更愿意使用ref(f)f显然取决于使用的上下文for_each_arg.