SORU
9 EKİM 2014, PERŞEMBE


Yapmak özel bir tür "tie-mümkün" (std ile uyumlu kravatı)

Ben özel bir türü uzatabilirim) göz önünde bulundurun:

struct Foo {
    int a;
    string b;
};

Nasıl bu nesnenin bir örneğini başvuruları std::tie, std::tuple yani atanabilir yapabilir miyim?

Foo foo = ...;

int a;
string b;

std::tie(a, b) = foo;

Başarısız girişim:

tuple<int&,string&> = Foo atama operatörünü aşırı yükleme atama operatörü sol taraftaki üyeleri nesnesi olmak zorunda olan ikili operatörlerinden biri olduğu için, mümkün değildir.

Uygun bir uygulama ile bunu çözmeye çalıştımdemet dönüşüm operatör. Aşağıdaki sürümleri başarısız:

  • operator tuple<int,string>() const
  • operator tuple<const int&,const string&>() const

Atama bir hata, bunu söylemeye neden "operator = tuple<int&,string&> = Foo aşırı değildir". Bu nedenle sanırım "dönüşüm her tür X şablon parametre deducing X operatörün=" birlikte iş yapma, aynı anda sadece bir tanesi.

Eksik teşebbüs:

Dolayısıyla dönüşüm operatörü uygulamaya çalıştımkravat tam yazın:

  • operator tuple<int&,string&>() constDemo
  • operator tuple<int&,string&>()Demo

Atama şimdi türleri artık (dönüşüm sonra) tam olarak aynı beri çalışıyor, ama bu destek olmasını isterdim üç senaryo için işe yaramaz:

  1. Eğer kravat farklı ama Cabrio türleri bağımlı değişken (int a; long long a; istemci tarafında, yani değişim) varsa, türleri tam olarak aynı olması beri başarısız. Bu Cabrio tipleri sağlayan başvurular bir demet bir demet atama olağan kullanım çelişmektedir.(1)
  2. Dönüşüm operatör başvuruları lvalue verilecek olan bir kravat dönmek gerekiyor. Bu geçici değerleri veya sabit üyeleri için işe yaramaz.(2)
  3. Eğer dönüşüm operatör sabit değilse, Atama da sağ el const Foo bir taraf için başarısız olur. Dönüşüm sabit bir sürüm uygulamak için, sabit-lik sabit konu üyelerinden uzakta kesmek için ihtiyacımız var. Bu çirkin ve tanımsız davranış sonucu kötü olabilir.

Ben sadece bir alternatif sunmak benim kendi tie fonksiyon sınıfı ile birlikte benim "tie-mümkün" nesneler, kendimi zorlamak için yinelenen işlevselliği std::tie Bu hoşuma gitmedi o değil de ben bulmak zor öyle geliyor ama yanlış yapmak zorunda).

Günün sonunda, sonuç bu kütüphane sadece başlığın bir uygulama için bir dezavantaj olduğunu düşünüyorum. Olmalarını istediğimiz kadar sihirli değiller.

DÜZENLEME:

Görünüşe göre, gerçek bir çözüm yukarıdaki tüm sorunları bir konuşma yok. Çok iyi bir cevap bu çözülebilir olmadığını açıklıyor. Özellikle, biri "başarısız girişim" işe yaraması mümkün değil. neden biraz ışık tutmak istiyorum


(1): korkunç kesmek için bir şablon olarak dönüştürme, yazma ve dönüştürme operatörü istenen üyesi türleri dönüştürmek için. Bu dönüştürülmüş üyeleri depolamak için nerede bilmiyorum çünkü korkunç bir hack. this demo statik değişkenleri kullanıyorum, ama bu iş parçacığı evresel değildir.

(2): hack (1) uygulanabilir.

CEVAP
9 EKİM 2014, PERŞEMBE


Mevcut girişimleri neden başarısız

std::tie(a, b) std::tuple<int&, string&>üretir. Bu tür std::tuple<int, string> vb ile ilgili değildir.

std::tuple<T...>birkaç atama operatörleri: var

  • Gereken atama-operatör, bir std::tuple<T...> varsayılan
  • Bir demet dönüştürme atama operatörüşablonbir tür parametresi ile std::tuple<U...> alır U..., paketi
  • Bir çift-dönüştürme atama operatörüşabloniki tür parametreleri ile U1, U2 std::pair<U1, U2> alır

Bu üç sürümleri için mevcut kopyalama ve türevleri hareket; aldıkları türleri de const& && ekleyin.

Atama operatörü şablonları işlev bağımsız değişken türü (OLUŞTURDUĞU türü yani atama-ifade) şablon onların argümanları anlamak için.

Foo, hiçbiri, dönüşüm operatör olmadan atama operatörleri std::tie(a,b) = fooiçin geçerli. Eğer Foo,dönüştürme operatörü eklerseniz o zaman sadece varsayılan atama-operatör uygun olur: Kesintinin almaz şablonu tarafından tanımlanan kullanıcı hesabı içine dönüşüm. Yani, atama-operatör türü şablonları Foo anlamak için şablon bağımsız olamaz.

Tek bir kullanıcı tanımlı beri örtülü dönüşüm dönüşüm bir dizi izin verilir, dönüşüm operatör dönüştürür türü varsayılan atama türünü tam olarak eşleşmesi gerekir. Yani, std::tie sonuç olarak aynı satır öğesi türleri kullanmak gerekir.

Öğe türleri (long Foo::a örneğin atama), Foo dönüştürme operatör dönüşümleri desteklemek için bir şablon yapmak gerekiyor

struct Foo {
    int a;
    string b;
    template<typename T, typename U>
    operator std::tuple<T, U>();
};

Ancak, std::tie öğe türlerini ifade etmektedir. Geçici bir başvuru döndürmek gerekir beri, operatör şablon içinde dönüşüm için seçenekler oldukça sınırlıdır (öbek, türü punning, statik, iş parçacığı yerel, vb.).

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Erica Griffin

    Erica Griffi

    8 HAZİRAN 2009
  • Khan Academy

    Khan Academy

    17 Kasım 2006
  • NPR

    NPR

    22 NİSAN 2006