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];
B
özel Bankası olduğunu unutmayın. Nasıl oluyor bu iş?operator B*()
sabit olduğunu unutmayın. Neden bu kadar önemli?Neden
static yes check(B*, int);
dahatemplate<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
İ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!
Nasıl 'dosyalarda grup' gerç...
Nasıl karma bir tablo işe yarıyor mu?...
Nasıl'In LMAX topu desen işe yarı...
Nasıl Google Anlık işe yarıyor mu?...
Nasıl RVM ve RBEnv gerçekten işe yarıy...