2011-04-09 9 views
9

oldukça şaşırdı: std::tr1::function bir Objective-C bloktan inşa edilmektedir yeteneğine sahiptir gibiNeden std :: tr1 :: işlevi Objective-C Blokları ile çalışır? Aşağıdaki kod aslında çalıştığını bulunca

std::vector<int> list /*= ...*/; 
std::tr1::function<void(int)> func = ^(int i) { 
    return i + 1; 
}; 

std::for_each(list.begin(), list.end(), func); 

görünüyor, ama emin değilim oldukça nasıl beri (son Ben kontrol ettim, onun uygulama özellikle blokları işlemez. Bir şekilde temel fonksiyon göstergesini dolaylı olarak mı emiyor? Ayrıca, bu davranış tanımlanmamış ve muhtemelen değişiyor mu?

+1

C++ bakış açınızdan, std :: işleviniz void f (int) 'gibi görünen herhangi bir şeye işaretçi tutar. Bir bloğun neye benzediyse, işe yarayacaktır (aksi halde değil). –

+0

@Bavazan Etiket düzenlemeleri için teşekkürler! –

cevap

5

Güncelleme: gerçekten sadece

std::tr1::function 'ın şablon parametresi çalışır imzayı çıkan fonksiyon nesnenin tanımlar neden, yanlış burada değil, tip aslında sarar. Bu nedenle, sarılmış nesnenin yalnızca bir imzası olan bir operator() sunması gerekir. Fonksiyon işaretçileri gibi, referansları engelleyin, dolaylı olarak operator() var (açıkçası, böylece onları arayabilirsiniz).

Eski, hatalı cevap

şiddetle blok çevreleyen kapsamdan herhangi bir değişken yakalamak değil çünkü çalışır şüpheli (bu nedenle yorum mantıklı). Bu durumda, sürdürülecek bir durum yoktur, bu nedenle bir blok referansı, bir çıplak fonksiyon gösterici olarak temsil edilebilir. Biz

std::vector<int> list /*= ...*/; 
int counter = 0; 
std::tr1::function<void(int)> func = ^(int i) { 
    counter++; 
    return i + counter; 
}; 

std::for_each(list.begin(), list.end(), func); 

kodunu değiştirirseniz o blok onunla etrafında counter arasında yakalanan değerini taşıyacak gerektiği gibi, derlemek için başarısız. Eğer Objective-C nesneleri ve Objective-C blokları için destek bir yeri vardır, bloklar sınırlı değildir Gibi blok davranabilirsiniz rağmen

+4

'std (:: tr1) :: function', imza işe yaradığı sürece, ne çağırması gerektiğini umursamıyor. Bu Objective-C bloğundan bir functor gibi bir şey almalısınız ve bir 'std (:: tr1) :: function' işlevi mükemmel bir şekilde çağırabilir. Ben bu Objective-C blokları C++ 0x lambdas'a benzer şekilde çalışıyorum ve std (:: tr1) :: function's lambdalarda gayet iyi çalışabilir, çünkü bunlar temel olarak funktörlerdir. :) – Xeo

+0

Elbette haklısın. Cevap değiştirildi. D'oh. – pmdj

+0

Bu gerçekten ilginç, teşekkürler! –

0

(tabii std::tr1::functionuygulanması özellikle blokları desteklemek için güncellendi sürece) Objective-C. C ve C++’daki blokları da kullanabilirsiniz. Daha fazla bilgi için bkz. this article.