Użyć ' class 'lub' typename ' dla parametrów szablonu? [duplikat]

to pytanie ma już odpowiedzi tutaj : Zamknięte 8 lat temu .

Możliwy duplikat:
C++ różnica słów kluczowych "typename" I "class" w szablonach

Przy definiowaniu szablonu funkcji lub szablon klasy w C++ można napisać tak:

template <class T> ...

Albo można napisać to:

template <typename T> ...

Czy jest dobry powód, aby wolą jeden nad drugim?


Zaakceptowałem najbardziej popularną (i interesującą) odpowiedź, ale prawdziwa odpowiedź brzmi: "Nie, Nie ma powodu, aby preferować jedną nad drugą."

  • są równoważne(z wyjątkiem zaznaczonych poniżej).
  • niektórzy ludzie mają powody, by zawsze używać typename.
  • niektórzy ludzie mają powody, aby zawsze używać class.
  • niektórzy ludzie mają powody, by używać obu.
  • Niektórzy nie dbają o to, którego używają.

Należy jednak pamiętać, że przed C++17 W przypadku parametrów szablonu wymagane było użycie class zamiast typename. Zobacz odpowiedź użytkownika 1428839 poniżej. (Ale ten konkretny przypadek nie jest kwestią preferencji, był wymogiem języka.)

 590
Author: Kristopher Johnson, 2008-10-17

10 answers

Stan Lippman mówił o tym tutaj. Myślałem, że to interesujące.

Summary : Stroustrup pierwotnie używał class do określania typów w szablonach, aby uniknąć wprowadzania nowego słowa kluczowego. Niektórzy członkowie komisji obawiali się, że to przeciążenie słowa kluczowego doprowadziło do zamieszania. Później Komitet wprowadził nowe słowo kluczowe typename, aby rozwiązać wieloznaczność składniową, i zdecydował, że będzie ono również używane do określania typów szablonów w celu zmniejszenia zamieszania, ale dla zgodności wstecznej, class zachował swoje przeciążone znaczenie.

 417
Author: itsmatt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-21 22:03:36

Według Scotta Myersa, efektywny C++ (3rd ed.) pkt 42 (co oczywiście musi być ostateczną odpowiedzią) - różnica jest "nic".

Zaleca się użycie "class", jeśli oczekuje się, że T będzie zawsze klasą, z "typename", jeśli można się spodziewać innych typów (int, char* whatever). Potraktuj to jako wskazówkę.

 316
Author: DarenW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-17 17:52:13

Jako dodatek do wszystkich powyższych postów, użycie słowa kluczowego class jest wymuszone (do C++14 włącznie) przy obsłudze parametrów szablonu , np.:

template <template <typename, typename> class Container, typename Type>
class MyContainer: public Container<Type, std::allocator<Type>>
{ /*...*/ };

W tym przykładzie typename Container wygenerowałby błąd kompilatora, coś w tym stylu:

error: expected 'class' before 'Container'
 154
Author: JorenHeit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-01 07:40:32

Wolę używać typename, ponieważ nie jestem fanem przeciążonych słów kluczowych (Jezu - ile różnych znaczeń mA static dla różnych kontekstów?).

 49
Author: Michael Burr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-17 17:52:29

Istnieje jest różnica i powinieneś preferować class od typename.

Ale dlaczego?

typename jest nielegalne dla argumentów szablonu, więc aby być spójnym, należy użyć class:

template<template<class> typename MyTemplate, class Bar> class Foo { };    //  :(
template<template<class>    class MyTemplate, class Bar> class Foo { };    //  :)
 17
Author: Mehrdad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

W odpowiedzi na Mike B , wolę używać 'class', ponieważ w szablonie 'typename' ma przeciążone znaczenie, ale 'class' nie. Weźmy przykład sprawdzonego typu integer:

template <class IntegerType>
class smart_integer {
public: 
    typedef integer_traits<Integer> traits;
    IntegerType operator+=(IntegerType value){
        typedef typename traits::larger_integer_t larger_t;
        larger_t interm = larger_t(myValue) + larger_t(value); 
        if(interm > traits::max() || interm < traits::min())
            throw overflow();
        myValue = IntegerType(interm);
    }
}

larger_integer_t jest nazwą zależną, więc wymaga preceedu 'typename', aby parser mógł rozpoznać, że larger_integer_t jest typem. klasa , z drugiej strony, nie ma takiego przeciążonego znaczenia.

To... albo jestem po prostu leniwy w sercu. Wpisuję "class" znacznie częściej niż "typename" , a więc łatwiej jest pisać. Albo może to być znak, że piszę za dużo kodu OO.
 9
Author: Aaron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:35

Po prostu czysta historia. cytat z Stan Lippman :

Powód obu słów kluczowych jest historyczny. W oryginalnej specyfikacji szablonu Stroustrup użył ponownie istniejącego słowa kluczowego klasy, aby określić parametr typu, a nie wprowadzić nowe słowo kluczowe, które może oczywiście zepsuć istniejące programy. Nie chodziło o to, że nie wzięto pod uwagę nowego słowa kluczowego, tylko o to, że nie było to konieczne, biorąc pod uwagę jego potencjalne zakłócenia. I aż do standardu ISO-C++, był to jedyny sposób aby zadeklarować parametr typu.

Ale należy używać typename zamiast class ! Zobacz link, aby uzyskać więcej informacji, ale pomyśl o następującym kodzie:

template <class T>
class Demonstration { 
public:
void method() {
   T::A *aObj; // oops ...
};
 9
Author: 5 revs, 4 users 81%user306683,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-22 18:41:38

To nie ma znaczenia, ale Klasa sprawia, że wygląda jak T może być tylko klasą, podczas gdy może być oczywiście dowolnym typem. Więc typename jest dokładniejszy. Z drugiej strony, większość ludzi używa klasy, więc prawdopodobnie jest to łatwiejsze do odczytania ogólnie.

 8
Author: Frederik Slijkerman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-17 19:26:10

Z tego co wiem, nie ma znaczenia którego z nich użyjesz. Są równoważne w oczach kompilatora. Użyj tego, który wolisz. Zwykle korzystam z zajęć.

 1
Author: Grant Limberg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-17 17:47:35

Rozszerzenie komentarza DarenW.

Gdy typename i class nie są akceptowane jako bardzo różne, nadal może być ważne, aby być ścisłym przy ich użyciu. Używaj klasy tylko wtedy, gdy jest naprawdę klasą, A Nazwa typowa, gdy jest podstawowym typem, np. char .

Typy te są rzeczywiście również akceptowane zamiast typename

Szablonchar myc = '/' >

Które w tym przypadku byłyby nawet lepsze od typename lub class.

Pomyśl o "odcieniu" lub zrozumiałości dla innych ludzi. I rzeczywiście rozważ, że oprogramowanie/Skrypty innych firm mogą próbować użyć kodu/informacji, aby odgadnąć, co dzieje się z szablonem (rozważ swig).

 -5
Author: muenalan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-28 12:37:56