Jaki jest kanoniczny sposób uzyskania macierzy bazowej surowego (C) tablicy (c) std :: tablica?
Nie ma sposobu na uzyskanie podstawowej tablicy C.
także, czy istnieje dobry powód, dla którego dane() zwraca wskaźnik surowy, a nie odniesienie do podstawowego surowca tablicy, czy jest to po prostu przeoczenie?
Wracamy: nie ma powodu, aby std::array
zapewniała podstawową tablicę C. Jak już powiedziałeś, tablica C byłaby przydatna (przez surowy wskaźnik) tylko z funkcjami uzyskującymi odniesienie do tablic C.
Kiedy ostatni raz miałeś funkcję:
void foo(int (&arr)[5])
Me? Nigdy. Nigdy nie widziałem funkcję z parametrem odniesienia C tablicy z wyjątkiem coraz rozmiaru tablicy (i odrzucając odnośniki):
template <class T, std::size_t N>
auto safe_array_size(T (&)[N]) { return N; }
Niech nurkować trochę się dlaczego parametry odniesienia do tablic nie są używane.
Na początek, ze wskaźnika obszaru C z oddzielnym parametrem wielkości był jedyny sposób na przekazanie tablic, ze względu na rozpad tablicowy i brak typu referencyjnego.
W C++ dostępne są alternatywy dla macierzy C, takich jak std::vector
i std::array
. Ale nawet gdy masz (legacy) C tablicę masz 2 sytuacje:
- jeśli przekazać go do funkcji C nie mają możliwość odniesienia, tak utkniesz do + wskaźnik wielkości
- kiedy chcesz przekazać go do funkcji C++, idiomatyczny sposób C++ ma przekazywać wskaźniki początku i końca.
Przede wszystkim iteratory begin + end są ogólne, akceptuje wszelkiego rodzaju kontenery. Ale nie jest rzadkością odniesienie do std::vector
, gdy chcesz uniknąć szablonów, więc dlaczego nie odwołać się do tablicy C, jeśli masz? Z powodu dużej wady: musisz znać rozmiar tablicy:
void foo(int (&arr)[5])
który jest wyjątkowo ograniczający.
Aby obejść ten problem trzeba zrobić to szablon:
template <std::size N>
void foo(int (&arr)[N])
który bije w celu uniknięcia szablonów, więc lepiej iść z rozpoczęciem + iteratory szablonów koniec zamiast.
W niektórych przypadkach (np obliczeń matematycznych na zaledwie 2 lub 3 wartości, które mają te same semantykę, więc nie powinny być oddzielne parametry) A specyficzny rozmiar tablicy jest wymagana, a czyniąc funkcja generic nie miałaby sensu. W takich przypadkach określenie rozmiaru tablicy gwarantuje bezpieczeństwo, ponieważ pozwala tylko przekazać tablicę o poprawnym rozmiarze podczas kompilacji; Dlatego jest to korzystne i nie jest „wielka wada”
Jednym z uroków (C i C++) jest ogromny zakres stosowalności. Więc tak, zawsze znajdziesz pola, które używają lub potrzebują unikalnej funkcji w wyjątkowy sposób. Biorąc to pod uwagę, nawet w twoim przykładzie nadal unikałbym tablic. Kiedy masz ustaloną liczbę wartości, które nie powinny być oddzielone semantycznie, myślę, że struktura byłaby właściwym wyborem w stosunku do tablic przez większość czasu (np. glm::mat4
zamiast float[4]
).
Ale nie zapominajmy, co to jest std::array
: nowoczesny zamiennik macierzy C. Jedną z rzeczy, których nauczyłem się podczas analizowania opcji, jest to, że nie ma absolutnego "lepszego niż". Zawsze jest "zależy". Ale nie w tym przypadku: std::array
powinien niewątpliwie zastąpić tablice C w interfejsach. Tak więc w rzadkim przypadku, gdy jako parametr referencyjny potrzebny jest kontener o ustalonym rozmiarze, nie ma sensu, aby umożliwić zachęcanie do korzystania z macierzy C, gdy już masz std::array
. Tak więc jedynym ważnym przypadkiem, w którym wystawienie podstawowej tablicy C z std::array
jest potrzeba, jest dla niektórych starych bibliotek, które mają parametry odniesienia C tablicy. Myślę jednak, że w szerszym kontekście dodanie tego do interfejsu nie jest uzasadnione. Nowy kod powinien używać struct (btw std::tuple
jest coraz łatwiejszy w użyciu dla każdego standardu) lub std::array
.
Przekazywanie odniesień do rozmiarów tablic jest trudne i nie jest szeroko stosowane; dlaczego by tak było, skoro używałbyś tylko surowej tablicy do interakcji z kodem C, który i tak nie ma żadnych odniesień? – BoBTFish
@WhiZTiM: OP oznacza, że nie ma możliwości przekształcenia 'std :: array' w coś, co można przekazać do 'myFunc (int (& k) [5])'. (Odniesienie do tablicy 5 int). –
Cóż, być może dlatego, że komitet zaprojektował 'std :: array' jako doskonałą alternatywę. Niedopuszczenie, aby łatwo uzyskać odniesienie do podstawowej tablicy kolorów, może być po prostu przesuwaniem w kierunku, w którym chcą nas zaprogramować. – StoryTeller