Verschil tussen trefwoorden ‘typenaam’ en ‘klasse’ in sjablonen?

Voor sjablonen heb ik beide verklaringen gezien:

template < typename T >
template < class T >

Wat is het verschil?

En wat betekenen die trefwoorden precies in het volgende voorbeeld (overgenomen uit het Duitse Wikipedia-artikel over sjablonen)?

template < template < typename, typename > class Container, typename Type >
class Example
{
     Container< Type, std::allocator < Type > > baz;
};

Antwoord 1, autoriteit 100%

typenameen classzijn uitwisselbaar in het basisgeval van het specificeren van een sjabloon:

template<class T>
class Foo
{
};

en

template<typename T>
class Foo
{
};

zijn gelijkwaardig.

Dat gezegd hebbende, er zijn specifieke gevallen waarin er een verschil is tussen typenameen class.

De eerste is in het geval van afhankelijke typen. typenamewordt gebruikt om te declareren wanneer u verwijst naar een genest type dat afhankelijk is van een andere sjabloonparameter, zoals de typedefin dit voorbeeld:

template<typename param_t>
class Foo
{
    typedef typename param_t::baz sub_t;
};

De tweede die je daadwerkelijk in je vraag laat zien, hoewel je het je misschien niet realiseert:

template < template < typename, typename > class Container, typename Type >

Bij het specificeren van een sjabloonsjabloonMOET het classtrefwoord worden gebruikt zoals hierboven — het is nietuitwisselbaar met typenamein dit geval (opmerking: sinds C++17 zijn beide trefwoorden in dit geval toegestaan).

U moet ook classgebruiken bij het expliciet instantiëren van een sjabloon:

template class Foo<int>;

Ik weet zeker dat er nog andere gevallen zijn die ik heb gemist, maar het komt erop neer: deze twee zoekwoorden zijn niet equivalent, en dit zijn enkele veelvoorkomende gevallen waarin u de een of de ander moet gebruiken.


Antwoord 2, autoriteit 22%

Voor het benoemen van sjabloonparameters zijn typenameen classequivalent. §14.1.2:

Er is geen semantisch verschil
tussen klasse en typenaam in a
sjabloonparameter.

typenameis echter mogelijk in een andere context bij het gebruik van sjablonen – om de compiler een hint te geven dat u naar een afhankelijk type verwijst. §14.6.2:

Een naam die wordt gebruikt in een sjabloondeclaratie
of definitie en dat is afhankelijk van
een sjabloon-parameter wordt verondersteld niet te
noem een type tenzij de toepasselijke naam
lookup vindt een typenaam of de naam
wordt gekwalificeerd door de typenaam van het zoekwoord.

Voorbeeld:

typename some_template<T>::some_type

Zonder typenamekan de compiler in het algemeen niet zeggen of je naar een type verwijst of niet.


Antwoord 3, autoriteit 5%

Hoewel er geen technisch verschil is, heb ik gezien dat de twee iets andere dingen aanduiden.

Voor een sjabloon die elk type als T moet accepteren, inclusief ingebouwde (zoals een array)

template<typename T>
class Foo { ... }

Voor een sjabloon die alleen werkt als T een echte klasse is.

template<class T>
class Foo { ... }

Maar houd er rekening mee dat dit puur een stijl is die sommige mensen gebruiken. Niet verplicht door de standaard of afgedwongen door compilers


Antwoord 4, autoriteit 2%

  1. Geen verschil
  2. Sjabloontypeparameter Containeris zelf een sjabloon met twee typeparameters.

Antwoord 5

Dit fragment komt uit het c++ primer-boek. Hoewel ik zeker weet dat dit niet klopt.

Elke typeparameter moet worden voorafgegaan door de trefwoordklasse of typenaam:

// error: must precede U with either typename or class
template <typename T, U> T calc(const T&, const U&);

Deze trefwoorden hebben dezelfde betekenis en kunnen door elkaar worden gebruikt in een sjabloonparameterlijst. Een sjabloonparameterlijst kan beide trefwoorden gebruiken:

// ok: no distinction between typename and class in a template parameter list
template <typename T, class U> calc (const T&, const U&);

Het lijkt misschien intuïtiever om het trefwoord typenaam te gebruiken in plaats van klasse om een sjabloontypeparameter aan te duiden. We kunnen immers ingebouwde (niet-klasse) typen gebruiken als argument voor het sjabloontype. Bovendien geeft typenaam duidelijker aan dat de naam die volgt een typenaam is. Typenaam werd echter toegevoegd aan C++ nadat sjablonen al wijdverbreid waren gebruikt; sommige programmeurs blijven uitsluitend les gebruiken


Antwoord 6

Er is geen verschil tussen het gebruik van OR ; d.w.z. het is een conventie die wordt gebruikt door C++ -programmeurs. Ik geef er zelf de voorkeur aan als het duidelijker beschrijft het gebruik; d.w.z. het definiëren van een sjabloon met een specifiek type 🙂

Opmerking: er is één uitzondering waarbij u klasse (en niet typenaam) moet gebruiken bij het declareren van een sjabloonsjabloonparameter:

sjabloon <sjabloonklasse T> klasse C { }; // geldig!

sjabloon <sjabloon typenaam T> klasse C { }; // ongeldig!

In de meeste gevallen definieert u geen geneste sjabloondefinitie, dus beide definities werken – wees gewoon consistent in uw gebruik…

Other episodes