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.
Może przejrzeć odniesienia wymienione na odwrocie [N2258] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf)? –
Aliasy szablonów to potrzeba, która została wprowadzona w C++ 11 i zdecydowano, że zamiast 'typedef' należy użyć' using'. – 101010
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