2016-04-13 11 views
4

Genel olmayan bir lamba ifadesinin yerel bir statik değişkene sahip olduğu bazı kodum var: kritik bölüm için bir muteks. basitleştiirlebilir şey:Yerel statik değişken, genel bir lambda ifadesinin tüm örneklemeleri arasında paylaşıldı

Şimdi, bu lambda ifadesi uygulanan kritik bölüm int & dışındaki türleri için harfi harfine yeniden olabilir ve ben Bildiricisi içinde auto ile int değiştirilmesi gibi basit bir değişiklik isterdi
int i = 0; 
auto lambda = [&i](int &v) 
{ 
    static std::mutex mutex; 
    std::lock_guard<std::mutex> lock(mutex); 
    /* critical section with v and i */}; 
} 

böyle: eğer bunu yaparsam

auto lambda = [&i](auto &v) 

yazık ki, lambda(int&) ve lambda(float&) kritik bölümünde kilidi yenmek edecek olan artık aynı yerel statik değişkeni paylaşmaz.

Ne tüm bu gereksinimleri karşılayacak kodunda en basit bir değişiklik olur:

  • ihtiyacım genericity sağlamak; ve
  • , kritik bölümün tüm örneklemelerinde paylaşılan tek bir mutex'e sahip olduğumu garanti eder;

    class Lambda 
    { 
    public: 
        Lambda(int &i) : i_(i) {} 
        template<class V> 
        void operator()(V &v) 
        { 
         std::lock_guard<std::mutex> lock(mutex_); 
         /* critical section with v and i_ */ 
        }; 
    private: 
        static std::mutex mutex_; 
        int &i_; 
    }; 
    std::mutex Lambda::mutex_; 
    
    int i = 0; 
    Lambda lambda(i); 
    

    Bu: ve

  • genel görünümden

bir şablon yöntemi ile bir sınıf, böyle bir şey ile lambda ifadeyi değiştirmek olacaktır çalışacak bir çözüm muteks'in göstermiyor Çalışır (özel referans i_ gibi uyarılar ile), ancak ilk lambda ifadesine kıyasla çok hantal görünüyor. Daha basit bir şey olur mu?

cevap

4

yapabilirsiniz init-yakalamak o kapak türünün bir üyesi değişkeni olarak tanımlanmaktadır sahip ve böylece kapatma nesnesinin tüm kopyaları aynı mutex'i paylaşacak benzer olacaktır bir shared_ptr:

auto lambda = [&i, m = std::make_shared<std::mutex>()](auto &v) 
    { 
     std::lock_guard<std::mutex> lock(*m); 
     /* critical section with v and i */ 
    }; 
+2

Bu Kritik bölümün tüm örneklemlerinde * tek bir muteks paylaşmamış olması * şeklindedir. Yanlış mıyım? – skypjack

+0

@skypjack, oops, Ben aslında 'make_shared' yazdım ama 'make_unique' için değiştirdiğime emin değilim (ki bu, bir ortak mutex ile kopyalanabilir hale getirmek istediğimde lambda kopmasız hale getirir). Aptal bir beyin fırtınası. Şimdi sabit. –

+1

Güzel. Ben de OP'nin '(auto & v)' yerine '(auto & v) 'yi görmek istediğini sanırım, çünkü onun genelleştirilmiş bir lambdaya sahip olması onun hedefiydi. – skypjack