SORU
29 Aralık 2014, PAZARTESİ


Nasıl void_t `çalışıyor

void_t SFİNAE tekniğini sundu modern şablon programlama (, ** 61 ** 62) hakkında Cppcon14 Walter Brown konuşmayı izledim.

Örnek:
Eğer şablon argümanlar oluşmuş 10 ** veren basit değişken bir şablon verilir

template< class ... > using void_t = void;

ve bir üye değişkeni varlığı kontrol eden aşağıdaki özellik denirüye:

template< class , class = void >
struct has_member : false_type
{ };

// specialized as has_member< T , void > or discarded (sfinae)
template< class T >
struct has_member< T , void_t< decltype( T::member ) > > : true_type
{ };

Bu işleri neden nasıl olduğunu anlamak için çalıştım. Küçük bir örnek bakimdan:

class A {
public:
    int member;
};

class B {
};

static_assert( has_member< A >::value , "A" );
static_assert( has_member< B >::value , "B" );

1.has_member< A >

  • has_member< A , void_t< decltype( A::member ) > >
    • A::member var
    • decltype( A::member ) iyi biçimlendirilmiş
    • void_t<> geçerli ve 19* *olarak değerlendirir
  • has_member< A , void > ve özel şablon seçer bu yüzden
  • has_member< T , void > true_type olarak değerlendirir

2.has_member< B >

  • has_member< B , void_t< decltype( B::member ) > >
    • B::member yok
    • decltype( B::member ) kötü oluşur ve sessizce (sfinae) başarısız
    • has_member< B , expression-sfinae > bu şablon atılır
  • derleyici varsayılan argüman olarak void has_member< B , class = void > bulur
  • has_member< B > 30* *olarak değerlendirir

http://ideone.com/HCTlBb

Soru:
1. Bu benim anlayış doğru mu?
2. Walter Brown varsayılan argüman o iş için bir void_t kullanılan tam olarak aynı tip olmak zorunda olduğunu belirtir. Bu yüzden mi? (Bu tür uyumlu olması için bir neden göremiyorum, iş yok sadece varsayılan türü değil mi?)

CEVAP
29 Aralık 2014, PAZARTESİ


Yazarken has_member<A>::value derleyici 33* *adını arar ve bulurİlköğretimsınıf şablonu, bu beyanı

template< class , class = void >
struct has_member;

(OP, bir tanım olarak yazılmış.)

Şablon tartışma <A> bu birincil şablon parametre listesi ile karşılaştırılır listesi. Birincil şablonu iki parametre vardır, ama sadece bir tane temin, bu yüzden geriye kalan parametre varsayılan şablon bağımsız değişken için varsayılan değer olarak ayarlanır: void. Eğer has_member<A, void>::value yazılı olsaydı.

Şimdi, şablon parametre listesi şablonu has_member herhangi bir uzmanlık karşılaştırılır. Eğer uzmanlık eşleşirse sadece, birincil şablon tanımını bir geri düşüş olarak kullanılır. Yani kısmi uzmanlaşma dikkate alınır:

template< class T >
struct has_member< T , void_t< decltype( T::member ) > > : true_type
{ };

Derleyici şablon bağımsız değişken desenler kısmi uzmanlaşma tanımlanan A, void eşleştirmeye çalışır: T void_t<..> tek tek. İlk olarak, şablon değişkeni kesintisi yapılır. Kısmi uzmanlaşma yukarıda hala "" bu tartışmaları. doldurulması gereken şablon parametreleri ile bir şablondur

İlk desen, T, derleyici şablon parametre T anlamak için izin verir. Bu önemsiz bir kesintinin, ama yine de T rapor verebilecek T const& gibi bir desen düşünün. Desen T şablon tartışma T A biz anlamak 48**,.

İkinci desen, şablon parametresi olmayan çıkarılabilir bir bağlamda görünür. Dolayısıyla, ikinci bağımsız değişken şablon void 51* *şablon parametresi anlamak.

Şablon değişkeni kesintisi bitti(*)şimdiçıkarılabilirşablon bağımsız değişken yerine kullanılır. Bu şuna benzer bir uzmanlaşma oluşturur:

template<>
struct has_member< A, void_t< decltype( A::member ) > > : true_type
{ };

54* *deyim şimdi değerlendirilebilir. İyi oluşturulmuş bir değişimden sonra, bu yüzden, hayırDeğiştirme Hatasıoluşur. Elde ederiz

template<>
struct has_member<A, void> : true_type
{ };

Şimdi, şablon değişkenleri has_member<A>::value orijinal ile sağlanan bu uzmanlık şablon parametre listesi karşılaştırabiliriz. Her iki tür de bu kısmi uzmanlaşma seçilir tam olarak eşleşmiyor.

Biz şablon olarak tanımlarken diğer taraftan:

template< class , class = int > // <-- int here instead of void
struct has_member : false_type
{ };

template< class T >
struct has_member< T , void_t< decltype( T::member ) > > : true_type
{ };

Biz aynı ihtisas bitiş:

template<>
struct has_member<A, void> : true_type
{ };

ama has_member<A>::value şablon bağımsız değişken bizim liste <A, int>. Bağımsız uzmanlık parametreleri eşleşmiyor, ve birincil şablonu bir geri düşüş olarak seçilmiştir.


(*)Standart, IMHO karışacak, yerine koyma işlemi ve açıkça belirtilen şablon argümanlar eşleşen içerirşablon değişkeni kesintisisüreç. Örnek (post-N4296) [temp.sınıf.spec.maçı] 2/:

Kısmi bir uzmanlaşma verilen gerçek şablon argüman listesini maçlar eğer kısmi uzmanlaşma şablon argüman çıkarılabilir eğer gerçek şablon bağımsız değişken listesi.

Ama bu değilsadecetüm şablon parametreleri kısmi uzmanlaşma indirilmeli var; o da bu değişimi başarmak zorundadır anlamına ve (gibi?) şablon bağımsız değişkenleri kısmi uzmanlaşma (yerine) şablon parametreleri ile uyumlu olmak zorunda. Farkında değilim unutmayınneredeStandart yerine bağımsız değişken listesi ve sağlanan bağımsız değişken listesi arasında karşılaştırma belirtir.

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Ludique

    Ludique

    21 NİSAN 2009
  • Murray Winiata

    Murray Winia

    2 ŞUBAT 2009
  • RaquelGamesBR

    RaquelGamesB

    20 HAZİRAN 2009