dmd 2.061'e geçenlerin karşılaştıkları bir durum, bazı kodlarının artık derlenemiyor olması. Bu rvalue'lar ve ref parametrelerle ilgili bir durum.
struct Yapı
{
int i;
void değiştir()
{
++i;
}
}
/* foo() parametresini referans olarak alıyor. Herhalde onda değişiklik
* yapacak. Bunun anlamlı olabilmesi için o parametrenin bir sol-değer
* (lvalue) olması gerekir. Sağ-değer (rvalue) olsa, yani örneğin geçici bir
* değişken olsa, yaptığı değişiklik kaybedilirdi.
*
* Not: C++ rvalue'ların const olmayar referans olarak gönderilmesine izin
* vermez.
*/
void foo(ref Yapı nesne)
{
nesne.değiştir(); /* <-- 'nesne' sağ-değer ise şüpheli bir durumdur çünkü
* bu değişiklik geçici bir nesnede yapılıyor
* demektir ve dolayısıyla kaybedilecektir.
*/
}
/* Bu işlev bir nesne oluşturur ve döndürür. Döndürdüğü sonuç bir
* sağ-değerdir; şu kod yasal değildir:
*
* nesneDöndür() = Yapı(42); // <-- DERLEME HATASI: Sağ-değere atamaya
// çalışıyor.
*/
Yapı nesneDöndür()
{
return Yapı(2);
}
void main()
{
/* Bu her zaman için yasaldı çünkü foo()'ya başlı başına bir nesne (yani
* lvalue) veriliyor. */
auto nesne = Yapı(0);
foo(nesne);
assert(nesne.i == 1);
/* dmd 2.060 ve önceki sürümleri hatalı davranıyordu ve aşağıdakilerden
* birisine izin veriyordu. (Hangisi olduğunu hatırlamıyorum. :))
*
* dmd 2.061 bu hatayı giderdi: Artık ikisi de derleme hatasıdır.
*/
foo(Yapı(1)); // <-- DERLEME HATASI
foo(nesneDöndür()); // <-- DERLEME HATASI
}
Tam çözümün ne olduğundan veya ne olacağından emin değilim. Söylendiğine göre, şimdiye kadar şablonlarla kullanılan 'auto ref' normal işlevlere de genişletilecekmiş ve bu konuda yardımcı olacakmış.
Şimdilik benim bildiğim tek çözüm, foo()'yu şablona dönüştürmek ve böylece parametresini 'auto ref' olarak işaretleyebilmek:
void foo(T)(auto ref T nesne)
{
/* ... */
}
Öyle yapınca derleyici lvalue ve rvalue durumuna göre iki işlev üretiyor. lvalue için 'ref' yazılmış gibi derliyor, rvalue için de 'ref' yazılmamış gibi.
Derleyicinin ürettiği işlevler şunun gibi oluyor:
import std.stdio;
// ...
void foo(ref Yapı nesne)
{
writeln("Sol-değer için");
nesne.değiştir();
}
void foo(Yapı nesne)
{
writeln("Sağ-değer için");
nesne.değiştir();
}
Yukarıdaki o iki işlevi kendimiz elle de öyle yazabilirdik. (Ve zaten ben de öyle yaptım! :)) main içinde bir lvalue iki de rvalue için çağrıldığından çıktı şöyle oluyor:
'Sol-değer için
Sağ-değer için
Sağ-değer için'
Ali
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]