2014-12-13 23 views
5

Dlaczego C++ 11 nie mają "typedefs szablonu", jakDlaczego C++ 11 nie ma szablonu typedef?

template<typename T> typedef std::vector<T, myalloc<T>> vec; 

Zamiast pozwalają one tylko nową składnię:

template<typename T> using vec = std::vector<T, myalloc<T>>; 
+0

Może przejrzeć odniesienia wymienione na odwrocie [N2258] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf)? –

+0

Aliasy szablonów to potrzeba, która została wprowadzona w C++ 11 i zdecydowano, że zamiast 'typedef' należy użyć' using'. – 101010

+0

Ponieważ składnia 'typedef' jest okropna (* rozszerza składnię deklaracji zmiennej *!), Szczególnie w przypadku typów funkcji. "używanie" jest bardziej czytelne; chyba że naprawdę potrzebujesz kompatybilności sprzed 11, po prostu zamień wszystkie swoje typedefs na 'using' i ciesz się, ile czystszego kodu dostaje. – Griwes

Odpowiedz

8

n1406 była propozycja przez Herb Sutter typedef dla "szablony" który naśladuje składnię w pytaniu. n1499, który proponuje zastąpić go "aliasem szablonu", który zawiera składnię, która jest obecnie obecna w C++ 11.

Jedna z głównych wad "szablonów typedef" jest adresowana w obu artykułach. Od n1406:

w istniejących praktyk, w tym w bibliotece standardowej, nazwy typu zagnieżdżone wewnątrz szablonów klas pomocnika są wykorzystywane w celu obejścia tego problemu w wielu przypadkach. Oto jeden z przykładów obejścia tego standardowego rozwiązania: ; Główną wadą jest konieczność napisania :: Wpisz, gdy używasz nazwy typedef.

template< typename T > 
struct SharedPtr 
{ 
    typedef Loki::SmartPtr 
    < 
     T,    // note, T still varies 
     RefCounted,  // but everything else is fixed 
     NoChecking, 
     false, 
     PointsToOneObject, 
     SingleThreaded, 
     SimplePointer<T> // note, T can be used as here 
    > 
    Type; 
}; 

SharedPtr<int>::Type p; // sample usage, “::Type” is ugly 

Co my naprawdę lubią być w stanie zrobić, to po prostu tak:

template< typename T > 
typedef Loki::SmartPtr 
    < 
    T,    // note, T still varies 
    RefCounted,  // but everything else is fixed 
    NoChecking, 
    false, 
    PointsToOneObject, 
    SingleThreaded, 
    SimplePointer<T> // note, T can be used as here 
    > 
    SharedPtr; 

SharedPtr<int> p;  // sample usage, “::Type” is ugly 

[...]

Rozwiązaniem jest brzydki, i dobrze byłoby, aby zastąpić to z najlepszą obsługą języków, która oferuje użytkownikom naturalną składnię szablonu C++ .

"Pierwsza obsługa języków" pojawia się w postaci aliasów szablonów. Teraz możemy spojrzeć na to, co ma do powiedzenia n1499:

W tym artykule skupimy się na opisywaniu mechanizmu aliasingu że umożliwia dwa semantyka wymienione w N1406 współistnieć zamiast być traktować jako wzajemnie się wykluczają. Po pierwsze rozważmy przykład zabawki:

template <typename T> 
class MyAlloc {/*...*/}; 

template <typename T, class A> 
class MyVector {/*...*/}; 

template <typename T> 
struct Vec { 
typedef MyVector<T, MyAlloc<T> > type; 
}; 

Vec<int>::type p; // sample usage 

Podstawowym problemem z tego idiomu, a głównym motywujący rzeczywistości dla tej propozycji jest to, że idiom powoduje parametry szablonu do pojawiają się non-wywnioskować kontekście. Oznacza to, że nie będzie można zadzwonić pod poniższą funkcję foo bez jawnego określenia argumentów szablonu .

template <typename T> void foo (Vec<T>::type&); 

Również składnia jest nieco brzydka. Wolimy raczej unikać zagnieżdżonych wywołań typu ::. Wolelibyśmy coś jak następuje:

template <typename T> 
using Vec = MyVector<T, MyAlloc<T> >; //defined in section 2 below 

Vec<int> p;  // sample usage 

pamiętać, że szczególnie unikać terminu „typedef szablonu” i wprowadzenia nowej składni udziałem pary „dzięki” i „=”, aby pomóc uniknąć nieporozumień: my nie są określając żadnych typów tutaj, jesteśmy wprowadzając synonim (np.alias) w celu uzyskania abstrakcyjnego identyfikatora typu (tj. wyrażenie typu) obejmującego parametry szablonu. Jeśli szablon parametry są stosowane w sytuacjach wywnioskować w ekspresji typu następnie gdy alias Szablon służy do utworzenia szablonu-id wartości z odpowiednimi parametrami matrycy można wywnioskować - bardziej na to nastąpi. W każdym razie teraz jest możliwe pisanie ogólnych funkcji , które działają w Vec<T> w kontekście dedukowalnym, a także poprawiona jest składnia . Na przykład możemy przepisać foo jak:

template <typename T> void foo (Vec<T>&); 

Mamy tu podkreślić, że jednym z głównych powodów, dla proponując szablonów aliasów było tak, że odliczenie argumentu i wywołanie foo(p) uda.

Widać więc, że n1499 rozwiązuje problemy w n1406, a także wprowadza składnię, która jest o wiele czystsza i łatwiejsza do odczytania.

+0

Dlaczego 'szablon typedef MyVector > Vec;' nie rozwiązać problem też? – steveire

Powiązane problemy