"Typename" kalit so'z qachon talab qilinadi?

Possible Duplicate:
Officially, what is typename for?
Where and why do I have to put the template and typename keywords?

quyidagi kodni ko'rib chiqing:

template
class C {
    struct P {};
    vector
vec; void f(); }; template void C::f() { typename vector
::iterator p = vec.begin(); }

Ushbu misolda nima uchun "typename" kalit so'zi kerak? "Typename" ning aniqlanishi kerak bo'lgan boshqa holatlar bormi?

45
qo'shib qo'ydi muallif Johannes Schaub - litb, manba

3 javoblar

Qisqa javob: qaram nomi bo'lgan ichki ismga murojaat qilganda, ya'ni noma'lum parametrga ega bo'lgan shablon misol ichida joylashgan.

Uzoqdan javob: C ++ da ob'ektlarning uchta katlami bor: qiymatlar, turlar va andozalar. Ularning hammasi nomlari bo'lishi mumkin, va ism faqatgina sizning qaysi darajadagi shaxsni aytmaydi. Aksincha, nomning tabiatiga oid ma'lumotlar kontekstdan olinishi kerak.

Ushbu natijani amalga oshirishning imkoni bo'lmaganda, siz buni aniqlab olishingiz kerak:

template  struct Magic;//defined somewhere else

template  struct A
{
  static const int value = Magic::gnarl;//assumed "value"

  typedef typename Magic::brugh my_type;//decreed "type"
 //     ^^^^^^^^

  void foo() {
    Magic::template kwpq(1, 'a', .5);//decreed "template"
   //       ^^^^^^^^
  }
};

Here the names Magic::gnarl, Magic::brugh and Magic::kwpq had to be expliciated, because it is impossible to tell: Since Magic is a template, the very nature of the type Magic depends on T -- there may be specializations which are entirely different from the primary template, for example.

What makes Magic::gnarl a dependent name is the fact that we're inside a template definition, where T is unknown. Had we used Magic, this would be different, since the compiler knows (you promise!) the full definition of Magic.

(Agar siz buni o'zingiz sinab ko'rishni istasangiz, siz foydalanishingiz mumkin Magic ning namunaviy ta'rifi. constexpr dan foydalanishni qisqartirish uchun qisqartirish uchun foydalaning; kompilyator, oldingi C ++ 11 shaklidagi statik element sobit deklaratsiyasini o'zgartirishga qodir emas.)

template  struct Magic
{
  static const T                    gnarl;
  typedef T &                       brugh;
  template  static void kwpq(int, char, double) { T x; }
};
template <> struct Magic
{
 //note that `gnarl` is absent
  static constexpr long double brugh = 0.25; //`brugh` is now a value
  template  static int kwpq(int a, int b) { return a + b; }
};

Foydalanish:

int main()
{
  A a;
  a.foo();

  return Magic::kwpq(2, 3); //no disambiguation here!
}
62
qo'shib qo'ydi
@Nils: const haqiqiy emas C ++.
qo'shib qo'ydi muallif Kerrek SB, manba
@PaoloM: sinf kodi shablonining A funktsiyasining ta'rifi birinchi bosqichda allaqachon ajralib turishi kerak, shuning uchun sintaksis uchun mantiqiy ma'noga ega bo'lishi kerak. Ikkinchi bosqichda, aniq kod T uchun Sehrli misolini aslida bir kwpq a'zosiga ega ekanligini tekshiramiz. tegishli imzo. (Va tahrir qilish uchun rahmat!)
qo'shib qo'ydi muallif Kerrek SB, manba
Izoh uchun tashakkur. Lekin men so'nggi narsani tushunolmayapman: Magic :: kwpq nomi T shablon parametridan kelib chiqqan holda, bu ikkinchi bosqichda hal qilinadi ikki fazali qidirish , o'ng? Shuning uchun derivat o'sha paytda tekshirish imkoniyatiga ega bo'lmasligi kerak (agar kwpq shabloni yoki turi yoki nima bo'lishidan qat'i nazar, uning nomi < i> darajadagi shaxs ?
qo'shib qo'ydi muallif Paolo M, manba

yineleyici P ga qaram bo'lganligi uchun typename kalit so'zini talab qiladi. Derleyici, iterator qiymatini yoki turini anglatadimi yoki yo'qmi deb taxmin qila olmaydi, shuning uchun typename ni urmasangiz, uning qiymatini qabul qilasiz. Shablonlar argumentiga bog'liq turdagi har qanday turdagi yoki qiymatlar tegishli bo'lgan kontekstda har doim kerak. Masalan, taglik klassi typename tagining asosiy klassi bo'lishi kerakligi sababli kerak emas.

Xuddi shu mavzu bo'yicha, derivatga ba'zi qaram ismlar qiymat o'rniga shablon vazifasi ekanligini bilish uchun ishlatiladigan shablon kalit so'zi mavjud.

10
qo'shib qo'ydi

Tizim nomi kalit so'zini shablon parametriga bog'liq bo'lgan har qanday turdagi ma'lumotlar talab qilinadi (shuning uchun kompilyator identifikatorning ( turi yoki qiymat ) semantikasini bilishi mumkin) birinchi paragrafdagi to'liq belgilar jadvali).


Not in the same meaning, and a bit less common, the lone typename keyword can also be useful when using generic template parameters: http://ideone.com/amImX

#include 
#include 
#include 

template 
7
qo'shib qo'ydi
Hech qachon "yolg'iz nomim" haqida bilmaganman, bu juda yaxshi!
qo'shib qo'ydi muallif Remy Lebeau, manba