2016-12-27 26 views

Odpowiedz

76

Można użyć std::tuple_size:

std::tuple_size<decltype(Foo::bar)>::value 
+13

W tym miejscu: różne klasy i funkcje dotyczące 'std :: tuple's (' std :: tuple_size', 'std :: tuple_element',' std :: get') mają przydatne specjalizacje do obsługi 'std: : array 'jak' std :: tuple '. – Quentin

-4

można używać jak:

sizeof Foo().bar 
+3

Zobacz [ten komentarz z OP] (http://stackoverflow.com/questions/41345182/get-size-of-stdarray-without-anance#comment69892397_41345182): on jest po liczbie elementów, a nie całkowitym rozmiarze. – Quentin

+0

@Happy - OP zmodyfikował odpowiedź: chce liczbę elementów w tablicy (8 w przykładzie), a nie 'sizeof' – max66

+3

uwaga: nie będzie działać dla klas bez domyślnego konstruktora –

4

Można zrobić to samo co dla starszych macierzach:

sizeof(Foo::bar)/sizeof(Foo::bar[0]) 
+2

lub użyj znacznie bardziej czytelnego ['std :: extent'] (http://en.cppreference.com/w/cpp/types/extent), ale nie jest to odpowiedź, ponieważ nadal wymagałoby to skonstruowania instancji. – Mgetz

+3

Kilka innych rzeczy, o których należy pamiętać: sizeof std :: array 'nie może być równe' sizeof int [4] ', to szczegół implementacji. Co więcej, jeśli masz zamiar skonstruować ['std :: array'] (http://en.cppreference.com/w/cpp/container/array), po prostu użyj [' size() '] (http: //en.cppreference.com/w/cpp/container/array/size) member – Mgetz

+2

Miałem na myśli 'sizeof (Foo :: bar)/sizeof (Foo :: bar [0])'. Nie było potrzeby użycia instancji Foo. – Waxrat

1

Zastosowanie:

sizeof(Foo::bar)/sizeof(int) 
+0

Próbowałem i otrzymuję tę samą wartość dla obu. '#include #include używanie przestrzeni nazw std; struct Foo { std :: array bar; }; int main() { cout << sizeof (Foo :: bar)/sizeof (int) << endl; cout << std :: tuple_size :: value << endl; return 0; } ' –

24

Pomimo, że good answer @ Jarod42, istnieje inne możliwe rozwiązanie oparte na decltype, które nie używa tuple_size.
Wynika minimalny, przykład roboczy, który działa w C++ 11:

#include<array> 

struct Foo { 
    std::array<int, 8> bar; 
}; 

int main() { 
    constexpr std::size_t N = decltype(Foo::bar){}.size(); 
    static_assert(N == 8, "!"); 
} 

std::array ma już funkcji członka constexpr nazwie size która zwraca wartość, którą szukasz.

+2

więc ma to ten sam problem co odpowiedź @ waxrat poniżej, wymaga ona konstrukcji, nawet jeśli ta konstrukcja ** może ** być' constexpr', w tym sensie 'std :: tuple_size' jest lepszą odpowiedzią, ponieważ nie robi ' t wymagać jakiejkolwiek konstrukcji lub zniszczenia w przypadku innym niż "prymityw". – Mgetz

+3

@Mgetz Nie powiedziałem, że jest lepiej. :-) ... Różne rozwiązania i odpowiedzi mogą pomóc przyszłym czytelnikom, bez względu na to, czy są akceptowane, czy nie. – skypjack

+0

stąd mój komentarz, starałem się zapewnić takim czytelnikom zrozumieć, dlaczego 'std :: tuple_size' jest lepszym wyborem. Powiedział, że prawdopodobnie zrobić "using array_size = std :: tuple_size" dla czytelności. – Mgetz

7

Możesz podać Foo członka public static constexpr.

struct Foo { 
static constexpr std::size_t bar_size = 8; 
std::array<int, bar_size> bar; 
} 

Teraz wiesz, rozmiar paska z Foo::bar_size i masz dodatkową elastyczność nazewnictwa bar_size na coś bardziej opisowego jeśli Foo kiedykolwiek ma wiele tablic o tym samym rozmiarze.

+0

Biorąc pod uwagę inne odpowiedzi pokazujące, że jest to możliwe bez "statycznej stałej", nie uważam tego za dobrą odpowiedź. – Tas

+0

@Tas: Moim zdaniem, problem polega na tym, że ta odpowiedź powoduje zwroty w tył: zamiast odpowiadać na pytanie, jak uzyskać liczbę elementów z istniejącej macierzy, mówi się o zadeklarowaniu znanej liczby i zmianie deklaracji macierzy w celu jej szablonu. że. Tak więc, członek 'static constexpr' naprawdę nie jest na co narzekać; nie zajmie miejsca w instancjach i będzie całkowicie zoptymalizowany w swojej jednostce tłumaczeniowej (chyba że jego adres zostanie zajęty, ale wtedy będzie to wymagało definicji out-of-line, więc). –

+0

@Tas @underscore_d Dzięki. Powodem, dla którego udzieliłem tej odpowiedzi jest to, że odpowiedzi o wysokim wyniku były skomplikowane. Rozmiar paska bez 'static constexpr' jest magiczną liczbą. To rozwiązanie usuwa magiczną liczbę i rozwiązuje problem za pomocą jednej prostej linii. –