byłem pisanie funkcje wyższego rzędu tak:Doskonałe-spedycyjnych wywoływalne obiekty w funkcji wyższego rzędu
template<typename F, typename... Args>
void doStuff(F f, Args&&... args)
{
// ...
f(std::forward<Args>(args)...);
// ...
}
A może zastąpić F f
z F&& f
.
Ale po tym, jak dowiedziałem się o ref-kwalifikatorach (ouch), sprawy się skomplikowały. Wyobraźmy sobie klasę funktora:
struct Foo {
void operator()(...) &;
void operator()(...) &&;
};
Wtedy moje wcześniejsze realizacje doStuff
będzie zawsze tylko wywołać metodę &
, ponieważ parametry są zawsze lwartościami.
Myślę, że sposób, aby rozwiązać ten jest wdrożenie doStuff
takiego:
template<typename F, typename... Args>
void doStuff(F&& f, Args&&... args)
{
// ...
std::forward<F>(f)(std::forward<Args>(args)...);
// ...
}
Jest to również sposób std::result_of
jest possibly implemented. Co chcę wiedzieć, czy jest jakaś wada do tej implementacji, tj. Czy powinienem zastąpić wszystkie moje wdrożenia HOF?
Wygląda dobrze, o ile 'f' nie zostanie ponownie użyty po tym. Możliwe, że 'operator()' będzie miał pewne skutki uboczne, które mogą modyfikować wewnętrzne elementy (przesunięcie na wewnętrznych elementach) 'f' (jeśli jakieś). Nie jestem jednak pewien, nie przemyślałem tego. Dobre pytanie. – Arunmu
@Arunmu If (1) metoda jest przeciążona na ref-kwalifikacjach, oraz (2) dzwoniący przekazuje funktor jako rwartość, mamy wystarczające powody, aby sądzić, że dzwoniący zamierza wywołać wersję '&&'. W tym przypadku prawdopodobnie rozsądne jest, aby perfekcyjnie przekazać każde wystąpienie 'f' w' doStuff' ... myślę. –
Nie widzę żadnego problemu z 'forward (f)' tak długo jak nie używaj 'f' ponownie w' doStuff' –
Praetorian