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%
typename
en class
zijn 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 typename
en class
.
De eerste is in het geval van afhankelijke typen. typename
wordt gebruikt om te declareren wanneer u verwijst naar een genest type dat afhankelijk is van een andere sjabloonparameter, zoals de typedef
in 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 class
trefwoord worden gebruikt zoals hierboven — het is nietuitwisselbaar met typename
in dit geval (opmerking: sinds C++17 zijn beide trefwoorden in dit geval toegestaan).
U moet ook class
gebruiken 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 typename
en class
equivalent. §14.1.2:
Er is geen semantisch verschil
tussen klasse en typenaam in a
sjabloonparameter.
typename
is 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 typename
kan 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%
- Geen verschil
- Sjabloontypeparameter
Container
is 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…