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].namektó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. EnteJest 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::stringlub boolnie zawiera tego, co się spodziewać, ponieważ std::pairnie ma semantykę z nim związane.
Konserwacja :
Pod względem konserwacji pairjest najgorszy. Nie możesz dodać pola.
tupletargi 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ć.
structjest 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::pairjest strukturą.