Wydajność :
To zależy.
W twoim konkretnym przypadku nie będzie różnicy w wydajności, ponieważ oba będą podobnie ułożone w pamięci.
W bardzo szczególnym przypadku (jeśli używałeś pustej struktury jako jednego z elementów danych), wówczas std::pair<>
potencjalnie mogliby skorzystać z pustej optymalizacji bazy (EBO) i mieć mniejszy rozmiar niż odpowiednik struktury. A mniejszy rozmiar ogólnie oznacza wyższą wydajność:
struct Empty {};
struct Thing { std::string name; Empty e; };
int main() {
std::cout << sizeof(std::string) << "\n";
std::cout << sizeof(std::tuple<std::string, Empty>) << "\n";
std::cout << sizeof(std::pair<std::string, Empty>) << "\n";
std::cout << sizeof(Thing) << "\n";
}
Drukuje: 32, 32, 40, 40 na ideone .
Uwaga: nie znam żadnej implementacji, która faktycznie używałaby sztuczki EBO dla zwykłych par, jednak ogólnie jest ona stosowana do krotek.
Czytelność :
Jednak oprócz mikrooptymalizacji nazwana struktura jest bardziej ergonomiczna.
Mam na myśli, map[k].first
że nie jest tak źle, podczas gdy get<0>(map[k])
jest ledwo zrozumiałe. Kontrast z map[k].name
którym natychmiast wskazuje, z czego czytamy.
Jest to tym bardziej ważne, gdy typy są konwertowalne na siebie, ponieważ ich przypadkowa wymiana staje się prawdziwym problemem.
Możesz także przeczytać o typowaniu strukturalnym a typowym. Ente
Jest to typ specyficzny, który może być obsługiwany tylko przez rzeczy, które oczekują Ente
, że wszystko może działać na std::pair<std::string, bool>
może działać na nich ... nawet gdy std::string
lub bool
nie zawiera tego, co się spodziewać, ponieważ std::pair
nie ma semantykę z nim związane.
Konserwacja :
Pod względem konserwacji pair
jest najgorszy. Nie możesz dodać pola.
tuple
targi są lepsze pod tym względem, o ile dodajesz nowe pole, wszystkie istniejące pola są nadal dostępne dla tego samego indeksu. Co jest tak nieprzeniknione jak wcześniej, ale przynajmniej nie musisz iść i je aktualizować.
struct
jest wyraźnym zwycięzcą. Możesz dodawać pola w dowolnym miejscu.
Podsumowując:
pair
jest najgorszy z obu światów,
tuple
może mieć niewielką krawędź w bardzo szczególnym przypadku (pusty typ),
- użyć
struct
.
Uwaga: jeśli używasz programów pobierających, możesz samodzielnie skorzystać z pustej sztuczki bazowej bez potrzeby, aby klienci wiedzieli o tym jak w struct Thing: Empty { std::string name; }
; dlatego Encapsulation to kolejny temat, którym powinieneś się zająć.
std::pair
jest strukturą.