2016-03-29 38 views
2

bazı Windows eski kodu taşıma ve ben tam anlamıyorum şu sorun koştu gcc/clang derlemek için bunu elde etmek için çalışırken:sözdizimi bulmaca

template<typename T> class Base 
{ 
public: 
    Base() {} 

    T m_var; 
}; 

template<typename T> class Derived : public Base<T> 
{ 
public: 
    Derived() 
    { 
    #if 1 
     Base<T>::m_var = 0; // fix - compiles with gcc/clang now 
    #else 
     m_var = 0;   // original - compiles only with MSVC++ 
    #endif 
    } 
}; 

gcc/clang gelen hatadır:

error: use of undeclared identifier 'm_var'

Maalesef vasıfsız eleman değişkenler türetilmiş sınıf yöntemlerinde başvurulan yerlerde yüzlerce vardır ve ben gerçekten, böylece tüm bu değiştirmek zorunda kalmak istemiyoruzile nitelikliyardım edebilirsem.

MSVC++ bunu yaparken neden gcc/clang'ın buna ihtiyaç duyduğunu açıklayabilir ve olası geçici çözümler önerebilir mi?

cevap

5

Base<T> bir bağımlı olduğu için, bu üyelere, nitelikli arama yoluyla erişilemez. Belirttiğiniz gibi, Base<T>::m_var aracılığıyla erişebilirsiniz. Başka bir seçenek this->m_var olacaktır.

Bunun için kısa bir çözüm olduğundan emin değilim. Bir seçenek T& m_var; veri üyesini Derived'a eklemek ve Base<T>::m_var referansına sıfırlamak olacaktır. Ekstra referans üyesi ile yaşayamazsanız, herhangi bir fonksiyonun başlangıcına T& m_var = this->m_var; numarasız bir m_var erişimi ekleyebilirsin.

+0

Özlü açıklama için teşekkürler - muhtemelen MSVC++ bunu şikayet olmadan derlemek yanlış mıdır? –

+1

@PaulR büyük olasılıkla, evet. Birkaç yıl önce, g ++ 'nun bu tür bir koddan şikayet etmediğini ve kuralı uygulamaya koymaya başladığında benzer kodları düzeltmem gerektiğini hatırlıyorum. – anderas

+1

@PaulR Evet, iki fazlı arama eksikliği nedeniyle. Üye sadece örnekleme zamanında aranır ve şablon tanımı AFAIK kontrol edildiğinde dikkate alınmaz. – TartanLlama

2

@TartanLlama'ın belirttiği gibi, üye şablon parametrelerine bağlı olan taban türü nedeniyle nitelenmemiş arama yoluyla kullanılamaz.

Basitçe Derived sınıf tanımına bir using Base<T>::m_var; ekleyin: Apart Base<T>::m_var veya this->m_var olarak erişmesini, şiddetle bunu erişilebilir hale getirmek istediğiniz her sınıf üyesi için sadece bir kez yazılmasına sahiptir beri tercih bir çözüm vardır . Bu şekilde, m_var, normal ad arama tarafından bulunacaktır.

+0

Geçici çözüm önerileri için teşekkürler - '… kullanarak ...' bu örnekte mükemmeldir, çünkü tüm türetilmiş yöntemleri kesmekten kaçınabileceğim anlamına gelir. –

+1

Evet, bunu yap, ben bir aptalım. – TartanLlama

+1

@PaulR Rica ederim! Bazı terimleri biraz gevşek/standart olmayan bir şekilde kullanabildiğim için üzgünüm. Buradaki standart dil ile aşina değilim ... – anderas