2016-07-27 7 views
6

Prosty i prosty: jaka jest zaleta wysyłania znaczników ponad normalną rozdzielczość przeciążania?Zalety wysyłki znaczników ponad normalną rozdzielczość przeciążenia

To są obie procesy w czasie kompilacji, prawda? Więc nie powinno być "zwycięzcy wydajności", jak sądzę. A każdy przypadek wysyłki tagów powinien być do pewnego stopnia przepisany/refaktoryzowany na normalne przeciążenie (prawdopodobnie przez dodanie wielu typów), prawda?

Oprócz odmiennego sposobu pracy i selekcji kandydatów, dlaczego miałbym preferować wysyłanie tagów z uwzględnieniem przeciążenia iw jakich przypadkach?

+7

Wysyłanie oparte na znacznikach uzyskuje się przez przeciążenie. – Arunmu

Odpowiedz

7

Tag dispatching to nazwa nadana technice zastosowanej do znalezienia prawidłowej funkcji przeciążenia. Technicznie jest to tylko przeciążanie.

Aby umieścić go z Boost strony:

Tag dyspozytorskich to sposób korzystania z funkcji przeciążenia wysyłką na podstawie właściwości typu, i jest często używany w parze z cech klas.

Możesz zobaczyć, jak cały plik biblioteki został użyty w standardowej bibliotece algorithm. Dla przykładu wystarczy wziąć pod uwagę, że istnieje algorytm AlgoX, który może być wykonywany dużo wydajniej na kontenerze zapewniającym dostęp losowy (np. vector) niż kontener zapewniający dostęp dwukierunkowy (list). Tak więc, przy wyborze algorytmu opiera się na jednym iterator type użyłby tag wysyłki użyciem iterator_traits

template <typename Iter> 
void AlgoXImpl(Iter first, Iter last, bidirectional_iterator_tag) { 
    //.....Algo specialized to bidirectional iterators 
} 

template <typename Iter> 
void AlgoXImpl(Iter first, Iter last, random_access_iterator_tag) { 
    //.....Algo specialized to random access iterators 
} 

template <typename Iter> 
void AlgoX(Iter first, Iter last) { 
    if (first == last) return; 
    AlgoXImpl(first, last, typename iterator_traits<Iter>::iterator_category()); 
} 

Jak widać, do prostego umysłu jest niczym innym przykładzie operatora przeciążenia jako kategorie są zasadniczo różne rodzaje.

Aby uzyskać bardziej realistyczny przykład, można wypróbować, w jaki sposób wdrożono std::rotate.

+0

Fakt, że wysyłanie znaczników jest intensywnie używane, nie daje odpowiedzi na pytanie, dlaczego jest używany. OP prawidłowo zauważa, że ​​jego efekty można łatwo osiągnąć przez zwykłe przeciążanie w hierarchiach typów znajdujących się pod jego kontrolą. Tak więc decydującym argumentem jest implementacja niestandardowego schematu dyspozytorskiego oddzielonego od definicji typów. Zobacz moją odpowiedź poniżej. –

+0

Istotą mojej odpowiedzi są w zasadzie pierwsze 4-5 wiersze, a nie, że są używane w STL. – Arunmu

+0

Duże pytanie uzupełniające tę odpowiedź: ** czy tag jest nieco szybszy i normalnie przeciążony? ** Przypuszczam, że nie, ponieważ oba są implementowane podczas kompilacji, ale wciąż pytam ... po prostu, aby być pewnym. – Dean

2

Tagi mogą być powiązane z typem, nawet z podstawowymi typami pierwotnymi, poprzez odpowiednie klasy cech. Np. Byłoby niemożliwe, aby typ wskaźnika był podklasą jakiejś koncepcji iteratora. Jednak klasa szablonowa może powiązać ją z pożądanym znacznikiem. Tak więc, wysyłki oparte na tagach zwiększają elastyczność, która pozwala na stworzenie schematu wysyłki, który nie może być już zdefiniowany przez zaangażowane typy.