std::reference_wrapper::operator()
wykonuje kawałek „magii” w niektórych przypadkach poza to, co bezpośrednie wywołanie funkcji będzie. Efekt ten jest określony jako (cytowanie N4296 [refwrap.invoke]):
template <class... ArgTypes>
result_of_t<T&(ArgTypes&&...)>
operator()(ArgTypes&&... args) const;
zwrócone: INVOKE(get(), std::forward<ArgTypes>(args)...)
. (20.9.2)
gdzie get()
zwraca odniesienie do tego, co opakowuje reference_wrapper
. INVOKE
opisano w 20.9.2 [func.require]
INVOKE(f, t1, t2, ..., tN)
zdefiniować w następujący sposób:
(1,1) - (t1.*f)(t2, ..., tN)
gdy f
jest wskaźnik funkcji do klasy T
i t1
jest obiekt typu T
lub odniesienie do obiektu typu T
lub odniesienie do obiektu typu pochodnego od T
;
(1,2) - ((*t1).*f)(t2, ..., tN)
gdy f
jest wskaźnikiem do funkcji do klasy T
i t1
nie jest jednym z typów opisanych w poprzednim akapicie;
(1,3) - t1.*f
gdy N == 1
i f
jest wskaźnikiem do danych należących do klasy T
i t1
jest obiektem typu T
lub odniesienie do obiektu typu T
lub odniesienie do obiektu typu pochodzącego od T
;
(1,4) - (*t1).*f
gdy N == 1
i f
jest wskaźnikiem do danych należących do klasy T
i t1
nie jest jednym z typów opisanych w poprzednim akapicie;
(1,5) - we wszystkich pozostałych przypadkach.
Wynikiem wywoływania ref(f)
zamiast po prostu f
jest to, że wskaźnik do funkcji członków i wskaźnik do członków dane mogą być „o nazwie” z odpowiednim obiektem wskaźnik/odniesienia jako parametr. Na przykład,
struct A { void foo(); };
struct B : A {};
struct C : B {};
for_each_arg(&A::foo, A{}, B{}, C{}, std::make_unique<A>());
nazwałbym foo
na A
, B
i C
tymczasowych obiektów i przedmiotów przechowywanych w unique_ptr
(DEMO). Dlaczego ktoś miałby preferować do korzystania z ref(f)
przez f
będzie oczywiście zależało od kontekstu, w którym używa się for_each_arg
.
To niepotrzebne. https://twitter.com/ericniebler/status/559798611991879684 – inf