2011-06-03 28 views
15

This snippet (this question'dan alınmıştır), g ++ (görüldüğü gibi) ile iyi bir şekilde derler, bu nedenle template dönüş türündedir. Buna karşılık, VC10 aşağıdaki hata ile bu kodu derlemek değildir:Hangi derleyici doğru? Templated dönüş türünden önce 'şablon' gerekli mi?

error C2244: 'A::getAttr' : unable to match function definition to an existing declaration

Ben template kaldırırsanız, VC10 mutludur ama g bu hatayı çığlıklar ++ çünkü: VC kırık tekrar

error: non-template 'AttributeType' used as template
note: use 'A::template AttributeType' to indicate that it is a template

bunu mı iki fazlı bir bakış mı yoksa sebebi nedir? Hangi derleyici burada? G ++ 'nın doğru olması gerektiğinden şüpheleniyorum, çünkü burada template belirsiz bir belleğim var; burada, rebind şablonundaki tüm ayırıcılar içinde.


Düzenleme: Bir kazananımız var: g ++/GCC (sürpriz sürpriz ...).


template <typename T, typename K> 
class A { 
public: 
    T t; 
    K k; 

    template <int i, int unused = 0> 
    struct AttributeType{ 
    }; 

    template <int i> 
    AttributeType<i> getAttr(); 

}; 

template <typename T, typename K> 
template <int i> 
typename A<T, K>::template AttributeType<i> A<T, K>::getAttr() { 
//    ^^^^^^^^ -- needed or not? 
    return t; 
} 


int main(){ 
    A<int,int> a; 
} 
+3

Mesaj söz konusu kodu. Yığın taşması destekler ve bunu kuvvetle destekler. –

+1

Genel olarak, standart uyumluluk için gayri resmi "başvuru derleyicisi" Comeau, kararını görüntülemek için snippet'inizi [burada] (http://www.comeaucomputing.com/tryitout/) göndermeyi deneyebilirsiniz. - DÜZENLEME: şimdi çalıştı, snippet Ideone'da olduğu gibi iyi derler. –

+0

@Merlyn: Bu soruyu kısa tutmak istedim, yine de yapıldı. – Xeo

cevap

10

GCC haklı. AttributeType, < açılı ayraç tarafından izlenen bağımlı bir şablon adıdır, bu nedenle template anahtar kelimesi belirsizliğini kaldırmak için burada gereklidir; bu, derleyiciye, takip edilenin bir şablon adı olduğunu netleştirir. Kural §14.2/4'te belirtilen:

When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6.2), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template.

@Johannes

burada çok iyi bir açıklama yazmıştır:

Where and why do I have to put the "template" and "typename" keywords?

+2

Teşekkürler, aradığım standart alıntıydı. – Xeo

İlgili konular