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>());
会在 A
、B
和 C
临时对象上调用 foo
以及 unique_ptr
中保存的对象(DEMO ).为什么 更喜欢 使用 ref(f)
而不是 f
显然取决于使用 for_each_arg
.
的上下文
为什么人们更喜欢调用 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)
whenf
is a pointer to a member function of a classT
andt1
is an object of typeT
or a reference to an object of typeT
or a reference to an object of a type derived fromT
;(1.2) —
((*t1).*f)(t2, ..., tN)
whenf
is a pointer to a member function of a classT
andt1
is not one of the types described in the previous item;(1.3) —
t1.*f
whenN == 1
andf
is a pointer to member data of a classT
andt1
is an object of typeT
or a reference to an object of typeT
or a reference to an object of a type derived fromT
;(1.4) —
(*t1).*f
whenN == 1
andf
is a pointer to member data of a classT
andt1
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>());
会在 A
、B
和 C
临时对象上调用 foo
以及 unique_ptr
中保存的对象(DEMO ).为什么 更喜欢 使用 ref(f)
而不是 f
显然取决于使用 for_each_arg
.