2013-03-15 18 views
12

Jestem w sytuacji w środowisku wielowątkowym, w którym mam wątek, który odbiera dane z gniazda i chcę je wysłać do kolejki komunikatów.Czy możesz przechwytywać tablice w lambda?

Na przykład coś takiego:

char buf[N]; 
size_t len = ::recv(buf, ...); 
queue.send([buf,len] { 
    //stuff 
}); 

Ale to nie będzie działać, ponieważ buf mógł wychodzić z zakresu lub nadpisane przez następne ::recv(). Teraz MOŻE skopiować go do string/std::vector/cokolwiek i przekazać ŻE rzecz przez wartość:

char buf[N]; 
size_t len = ::recv(buf, ...); 
std::string my_data(buf, len); 
queue.send([my_data](){ /* stuff */ }); 

Ale ja poniesienia dodatkową kopię, prawda? Czy istnieje sposób na uzyskanie tej samej funkcjonalności bez dodatkowego obciążenia?

+3

Dlaczego nie używasz 'std :: array'? Nie musisz przekazywać wartości, możesz przekazać przez referencję, tj. '[&]'. – Rapptz

+2

'buf' może wyjść poza zakres, ale kopia w lambda nie będzie. Nadal możesz mieć dodatkową kopię, w zależności od tego, czy 'queue.send' jest zoptymalizowane do akceptowania referencji rvalue. –

Odpowiedz

17

Tak, możesz. Standard mówi, że (5.1.2p21):

Podczas oceny wyrażenia lambda, jednostki przechwycone przez kopiowanie są używane do bezpośredniego inicjowania każdego odpowiadającego niestatycznego elementu danych wynikowego obiektu zamknięcia. (W przypadku elementów tablicy elementy tablicy są inicjowane bezpośrednio w rosnącej kolejności w indeksie).

co wyjaśnia, że ​​lambda może przechwytywać tablicę przez kopiowanie.

+2

Oh cool, cała tablica buf zostaje skopiowana, a nie tylko wskaźnik? To całkiem fajne! – Barry

+9

@Barry: Tak długo, jak przechwycona zmienna jest faktycznie tablicą, a nie tylko wskaźnikiem do jednego, tak. –

Powiązane problemy