std::ref 在此函数中有什么用?

What is std::ref useful for in this function?

为什么人们更喜欢调用 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;
}

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

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

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

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

中有描述

Define INVOKE(f, t1, t2, ..., tN) as follows:

(1.1) — (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of type T or a reference to an object of type T or a reference to an object of a type derived from T;

(1.2) — ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of the types described in the previous item;

(1.3) — t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is an object of type T or a reference to an object of type T or a reference to an object of a type derived from T;

(1.4) — (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 is not one of the types described in the previous item;

(1.5) — f(t1, t2, ..., tN) in all other cases.

调用ref(f)而不是简单地调用f的结果是指向成员函数的指针和指向成员数据的指针可以"called"具有适当的对象pointer/reference 作为参数。例如,

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

会在 ABC 临时对象上调用 foo 以及 unique_ptr 中保存的对象(DEMO ).为什么 更喜欢 使用 ref(f) 而不是 f 显然取决于使用 for_each_arg.

的上下文