2015-03-11 17 views
5

Uygulamamın yaptığı şeylerden biri, bir soketten gelen yükleri dinleyip almak. Asla engellemek istemiyorum. Alınan her yük üzerinde, bir nesne oluşturmak ve onu bir çalışan iş parçacığına aktarmak ve prototip kodunun nasıl işlediğini daha sonraya kadar unutmak istiyorum. Ama üretim kodu için uygun async yöntemini kullanarak karmaşıklığı (benim app büyük) azaltmak istiyorum. Async bir sözden yapılan bir geleceği alır. Bunun çalışması için aşağıda Xxx sınıfı tarafından temsil edilen POD olmayan nesnem üzerinde bir söz yaratmam gerekiyor. Bunu yapmanın bir yolunu görmüyorum (aşağıdaki örnek kodumdaki hatayı okuyun). Burada uyumsuzluk kullanmak uygun mu? Eğer öyleyse, ben int daha karmaşıktır bir söz/gelecekteki nesne oluşturmak nasıl (tüm kod örnekleri ben kullanım int ya da void bkz ettik): En uygulaması kusurlu gibibir std :: POD olmayan bir nesneden yapılacak söz verebilir mi?

#include <future> 
class Xxx //non-POD object 
{ 
    int i; 
public: 
    Xxx(int i) : i(i) {} 
    int GetSquare() { return i * i; } 
}; 

int factorial(std::future<Xxx> f) 
{ 
    int res = 1; 
    auto xxx = f.get(); 
    for(int i = xxx.GetSquare(); i > 1; i--) 
    { 
    res *= i; 
    } 
    return res; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    Xxx xxx(2); // 2 represents one payload from the socket 
    std::promise<Xxx> p; // error: no appropriate default constructor available 
    std::future<Xxx> f = p.get_future(); 
    std::future<int> fu = std::async(factorial, std::move(f)); 
    p.set_value(xxx); 
    fu.wait(); 
    return 0; 
} 
+1

Varsayılan olarak bir "Xxx" vermeyi denediniz mi? – Angew

+0

Neden "xxx" ifadesini async işlevine geçirmiyorsunuz? İki yönlü "geleceğin" iletişimine gerçekten ihtiyacın var mı? Bu sadece her iki dişin birbirini beklediği anlamına gelir. –

+0

Anladım. Zaten yük veriye sahip olduğum için, bir söz/gelecek vaat etmeye gerek yok. Karmaşık argümanlarımla asnyc'in _Fty && _Fnarg, _ArgTypes && ... _Args yapıcısını kullanın. – rtischer8277

cevap

5

Mike zaten yanıtladığı gibi, std::promise'un Visual C++ uygulamasında kesinlikle bir hatadır, yapmanız gereken şey işe yaramalıdır.

Ama yine de neden bunu yapmanız gerektiğini merak ediyorum. Belki de, örneğin, basit örnek tutmak için başka bir gereksinim var, ancak bu kodu yazmanın açık yolu olurdu:

#include <future> 

class Xxx //non-POD object 
{ 
    int i; 
public: 
    Xxx(int i) : i(i) {} 
    int GetSquare() { return i * i; } 
}; 

int factorial(Xxx xxx) 
{ 
    int res = 1; 
    for(int i = xxx.GetSquare(); i > 1; i--) 
    { 
    res *= i; 
    } 
    return res; 
} 

int main() 
{ 
    Xxx xxx(2); // 2 represents one payload from the socket 
    std::future<int> fu = std::async(factorial, std::move(xxx)); 
    int fact = fu.get(); 
} 
+0

Otomatik xxx = f.get(); Hala bir zamanda geçmeyeceğim için hala gerekli mi? – rtischer8277

+0

Oops, iyi benekli. O şeyi değiştirmeyi unuttum, şimdi düzeltildi. –

+0

Bu gerçekten bir böcek. [Hata raporu] gönderdim (https://connect.microsoft.com/VisualStudio/feedback/details/2229765/bug-std-promise-t-requires-that-t-is-defaultconstructible). Bu hata, dosyasında bir todo öğesi olarak listeleniyor ("// TODO: _Associated_state ctor, _Ty varsayılan olarak yapılandırılabilir") böylece geliştiriciler zaten bunun farkındadır. –

3

geliyor. Varsayılan bir kurucuya gerek yoktur ([utility.arg.requirements] 'ın genel kütüphane gereksinimleri) ve GCC kodunuzu kabul eder (garip Microsoftish _tmain standardını main standardına dönüştürdükten sonra).

Farklı bir derleyici ve işletim sistemine geçiş yapardım. Bu sizin için bir seçenek olmayabilir, bu yüzden derse, onu mutlu tutmak için varsayılan bir kurucu verebilirdiniz.

+0

Yup, kesinlikle uygulamada bir hata. "" sözü, başlatılmamış bir arabellek oluşturmalı ve "set_value" çağrıldığında yalnızca bir "Xxx" nesnesini oluşturmalıdır. Başka bir geçici çözüm 'std' bir –

+0

yerine 'boost :: vaat' kullanmak için geri gelen bir C++ MFC-hugger değilim. Java ve C# teknik digresyonlarını atladım ve tüm yeni C++ kütüphaneleri (GUI, şifreleme, vb.) Ile birlikte bu yeni ISO paralellizasyon yeteneklerini kullanmaktan mutluluk duyuyorum. Aslında, 2014 Build'teki Herb Sutter'e göre, async uygulamalarını standartlar topluluğuna eklenmek üzere sunan MS'ydi. [Utility.arg.requirements], bir sözde herhangi bir arg türünü geçebilmeniz gerektiğini varsayar mı? – rtischer8277

+1

[utility.arg.requirements] sadece 'söz' özgü değil, 'Genel olarak, varsayılan bir kurucu gerekli değildir.' –

İlgili konular