Il tipo di cattura lambda non può essere controllato da nomi dipendenti da modello.
Tuttavia, si potrebbe ottenere l'effetto desiderato, delegando la creazione lambda interna a una funzione di sovraccarico:
template<class T>
auto make_monad(T&& arg) {
return [captive = std::forward<T>(arg)](auto&& a) {
std::cout << __PRETTY_FUNCTION__ << " " << a << '\n';
return 1;
};
}
template<class T>
auto make_monad(std::reference_wrapper<T> arg) {
return [&captive = static_cast<T&>(arg)](auto&& a) {
std::cout << __PRETTY_FUNCTION__ << " " << a << '\n';
return 1;
};
}
int main() {
auto monad = [](auto&& captive) {
return make_monad(std::forward<decltype(captive)>(captive));
};
int n = 1;
monad(1)(1);
monad(n)(2);
monad(std::ref(n))(3);
}
Uscite:
make_monad(T&&)::<lambda(auto:1&&)> [with auto:1 = int; T = int] 1
make_monad(T&&)::<lambda(auto:1&&)> [with auto:1 = int; T = int&] 2
make_monad(std::reference_wrapper<_Tp>)::<lambda(auto:2&&)> [with auto:2 = int; T = int] 3
io non voglio cattura reference_wrapper per riferimento, voglio catturare il riferimento che detiene per riferimento. Il reference wrapper è meglio essere un riferimento, ma dato che l'operatore di chiamata (noto anche come operatore ".") Non può essere sovraccaricato, alla fine della giornata fallisce in modo piuttosto miserabile.
In questo caso non è necessario modificare il tipo di acquisizione per std::reference_wrapper<T>
. Invece, come si può catturare per valore come qualsiasi altro tipo di argomento e nel sito utilizzo scartare l'argomento prima:
template<class T> T& unwrap(T& t) { return t; }
template<class T> T& unwrap(std::reference_wrapper<T> t) { return t; }
auto monad = [](auto && captive) {
return [captive](auto && a) { // <--- Capture by value.
auto& captive_ref = unwrap(captive); // <--- Unwrap before usage.
return 1;
};
};
fonte
2014-11-26 15:48:02
Non è il punto di 'reference_wrapper' che è come un riferimento, tranne che può essere passato in giro per valore senza un problema? Perché allora * si * digita il tipo che vuoi catturare per riferimento? Cosa c'è di sbagliato nel catturare tutto per valore? – hvd
@hvd Non voglio acquisire 'reference_wrapper' per riferimento, voglio catturare il riferimento che detiene per riferimento. Il reference wrapper è meglio essere un riferimento, ma dato che l'operatore di chiamata (noto anche come operatore ".") Non può essere sovraccaricato, alla fine della giornata fallisce in modo piuttosto miserabile. – pat
Grazie per il chiarimento. Questo ha più senso. Quindi non vuoi catturare 'captive' per riferimento se è un' reference_wrapper', vuoi catturare 'captive.get()' per riferimento, giusto? – hvd