SORU
26 Mayıs 2010, ÇARŞAMBA


Nasıl is_base_of `işe yarıyor mu?

Nasıl aşağıdaki kod çalışıyor mu?

typedef char (&yes)[1];
typedef char (&no)[2];

template <typename B, typename D>
struct Host
{
  operator B*() const;
  operator D*();
};

template <typename B, typename D>
struct is_base_of
{
  template <typename T> 
  static yes check(D*, T);
  static no check(B*, int);

  static const bool value = sizeof(check(Host<B,D>(), int())) == sizeof(yes);
};

//Test sample
class Base {};
class Derived : private Base {};

//Exspression is true.
int test[is_base_of<Base,Derived>::value && !is_base_of<Derived,Base>::value];
  1. B özel Bankası olduğunu unutmayın. Nasıl oluyor bu iş?

  2. operator B*() sabit olduğunu unutmayın. Neden bu kadar önemli?

  3. Neden static yes check(B*, int); daha template<typename T> static yes check(D*, T); daha iyi ?

Not: İndirgenmiş versiyonu (makrolar kaldırılır) boost::is_base_of. Ve bu uygulamaları geniş bir yelpazede üzerinde çalışır.

CEVAP
26 Mayıs 2010, ÇARŞAMBA


İlişkin ise

Bir an için diyelim B aslında D bir tabanı olduğunu varsayalım. check, çağrı için iki sürümü Host D* dönüştürülebilir çünkü uygulanabilirveB*. Bir kullanıcı D* B* Host<B, D> 13.3.3.1.2 tarafından açıklanan dönüşüm sırası sırasıyla tanımlanır. Sınıf dönüştürebilirsiniz dönüştürme fonksiyonları bulmak için aşağıdaki aday fonksiyonları 13.3.1.5/1 göre check ilk fonksiyonu için elde edilir

D* (Host<B, D>&)

İlk dönüştürme fonksiyonu B* D* dönüştürülebilir. çünkü bir aday değil.

İkinci işlevi için, aşağıdaki adaylar var:

B* (Host<B, D> const&)
D* (Host<B, D>&)

Şu ana nesne al bu iki dönüştürme fonksiyonu seçer. İlk sabit başvuru ile alır, ikincisi değil. İkincisi çok daha iyi bir maç için olmayan sabit *this nesne (. böylece ^em>dolaylı nesne değişkeni) 13.3.3.2/3b1sb4 saniye B* dönüştürmek için kullanılır check işlevi.

Eğer istiyorsanızKaldırinş aşağıdaki aday olurdu

B* (Host<B, D>&)
D* (Host<B, D>&)

Bu constness artık seçin edemeyiz anlamına gelir. Sıradan aşırı çözümleme bir senaryoda, çağrı şimdi normalde dönüş türü aşırı çözümleme katılmak olmaz çünkü belirsiz olurdu. Dönüştürme fonksiyonları için, ancak, bir arka kapı var. Eğer iki dönüştürme işlevleri aynı derecede iyi olup olmadığını, sonra da dönüş türü 13.3.3/1 göre en iyi kim karar verir. Eğer sabit kaldırmak istiyorsanız, bu nedenle, o zaman ilk B* daha iyi B* D* B* dönüştürür nedeniyle alınmış olur.

Şimdi ne kullanıcı tanımlı dönüştürme sırası mı iyi? İkinci ya da ilk kontrol işlevi için mi? Kural kullanıcı tanımlı dönüştürme dizileri aynı dönüşüm veya 13.3.3.2/3b2 göre fonksiyon oluşturucu kullanıyorsanız mukayese edilebilir. Bu tam olarak böyle işte: Hem kullanım ikinci dönüştürme fonksiyonu. Bu sebeple dikkat edininşderleyici ikinci dönüştürme işlevi almak için zorlar, çünkü bu önemlidir.

Onları karşılaştırabiliriz beri - hangisi daha iyi? Kural dönüşüm dönüş türü daha iyi dönüşüm hedef türü wıns (13.3.3.2/3b2 tekrar) işlevi. Bu durumda D* daha iyi D* çevirir B* daha. Böylece ilk işlevi seçilir ve mirası kabul ediyoruz!

Biz asla gerektiğinden dikkat edinaslındabir temel sınıf, dönüştürmek, böylece daha iyi anlarızözel bir mirasbir D* dönüştürmek çünkü ister B* 4.10/3 göre miras şeklinde bağımlı değil

İlgili değilse

Şimdi miras ile ilgili olduğunu varsayalım. İlk fonksiyonu böylece aşağıdaki adayımız var

D* (Host<B, D>&) 

İkincisi için biz şimdi başka bir set var

B* (Host<B, D> const&)

Eğer devralma ilişki almadık diye B* 48 *convert edemez bu yana, biz şimdi kullanıcı tanımlı iki dönüşüm dizileri arasında ortak bir dönüştürme işlevi var! Böylece olurdukbelirsizilk işlevi bir şablon olduğu için değil. Şablonları 13.3.3/1 göre aynı derecede iyi olmayan bir şablon işlevi olduğunda ikinci seçenek. Böylece, non-şablon işlevi (ikinci bir) seçin ve B D arasında miras yoktur farkındayız!

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Adam Washington

    Adam Washing

    12 Mayıs 2006
  • hans peder sahl

    hans peder s

    22 Temmuz 2009
  • Submissions101

    Submissions1

    23 ŞUBAT 2007