2011-03-05 25 views
5

Biraz araştırma yaptıktan sonra, C++ 0x öğesinin bir tuple'daki öğeleri bellekte geriye doğru kaydettiğini buldum.C++ 0x Tuples Elements Öğeleri Geriye doğru

Örneğin, bu kodu almak: GCC 4.5.2 ile derlenmiş

std::tuple<char, char, char> x('\0', 'b 'a'); 
char* y = (char*)&x; 
std::cout << sizeof(x) << std::endl; 
std::cout << y << std::endl;

, aşağıdaki çıktıyı almak:

3 
ab

Bu başlangıçta beni şaşırtıyordu. Veriler neden geriye doğru depolanıyor? taban sınıfı geçen öğesi içeren

template<typename head, typename... tail> class tuple<head, tail...> : public tuple<tail...> 
{ 
    head value; 
    ... 
};

Çünkü, bir sonraki türetilmiş sınıf, vb sondan ikinci fiili içerir: GNU istemeden karartılmış başlıklarını yoluyla avcılık sonra Uygulamanın bu benzer olduğunu fark şablon argümanlarının sırası tersine çevrilir.

Tuples'e ilk girdiğimde, renkleri, doku koordinatlarını, normalleri ve noktaları bir araya getiren bir dizi vertex verisini ayarlayan glInterleavedArrays() gibi bir işlev için kullanabileceğimi düşündüm. Tabii ki, eğer bir dizi tupl yaparsam, bu verilerin tersine girilmesi gerekir, bu da argümanları doğru sıraya koymayı unutursanız gerçekten garip hatalara yol açabilir.

Böyle bir şeye ne dersin peki? GCC 4.5.2 altında

template<typename... head, typename tail> class tuple<head..., tail> : public tuple<head...> 
{ 
    tail value; 
    ... 
};

:

error: parameter pack argument ‘head ...’ must be at the end of the template argument list

bu gelecekte kullanılabilir hale sürece, hemen hemen bu uygulamaya başka bir yol bulmaya mahsur kaldım. Başka bir yolu var mı? GCC'yi düzgün bir şekilde sipariş edilmiş bir bellek bilgisine sahip olmak için kandırmanın bir yolu var mı?

cevap

5

Bulduğun tuple düzeni, belirtilmemiş bir uygulama detayıdır. Diğer uygulamaların başka düzenleri olacaktır. Buna yazarsanız, gcc'nin düzenine bağlı olarak, kodunuz diğer std :: lib'lerine taşınabilir olmayabilir.

libc++ Tuple uygulamasının (örneğin) ters sırada (düzende) düzeni vardır.

5

Niçin tuple uygulamasının ne olduğunu umursuyorsunuz? Program to an interface, not an implementation.

Yalnızca reklamı yapılan arabirim üzerinden tuple'ı kullanırsanız, nesnelerinizi yerleştirdiğiniz sırayla alırsınız. Bunun yerine, içeriğine doğrudan girerek kapsüllemeyi keserseniz; Örneğin, tüm bahisler kapalıdır.

+0

Zaten neden - 'glInterleavedArrays()', araya girilen bir veri dizisini isteyen bir işlev olduğunu belirtmiştim. Amacım, bu prensibe dayanan bir tuple sınıfı yaratmaktı. Verileri bir dizi dizide arayarak verileri GL'ye iletebildim. Daha fazla bilgi isterseniz, OpenGL belgelerine bakın: http://www.opengl.org/sdk/docs/man/xhtml/glInterleavedArrays.xml –

+0

@RetroX: Daha sonra, tuple uygulamasına güvenmek yerine, bir nesne istiyorsanız Ara yüzü bilinen bir sırada bir seri hale getirme aracı sağlar. Her iki durumda da arayüzün garantiyi sağlamasını istersiniz, böylece uygulama ayrıntılarına bağlı kalmazsınız. –

İlgili konular