2017-08-04 2 views
6

używam następującą funkcję szablonu policzyć elementy tablicy:Jak policzyć elementy macierzy C++ z funkcji szablonu, pozwalając jednocześnie na pustych tablic

#include <stdio.h> 

template<typename T, size_t N> constexpr 
size_t countof(T(&)[N]) 
{ 
    return N; 
} 

int main(void) 
{ 
    struct {} arrayN[] = {{}, {}, {}}; 
    printf("%zu\n", countof(arrayN)); 
    return 0; 
} 

To działa, ale nie z pustej tablicy:

struct {} array0[] = {}; 
printf("%zu\n", countof(array0)); 

gcc 5.4 wyjście:

error: no matching function for call to ‘countof(main()::<anonymous struct> [0])’ 
note: candidate: template<class T, long unsigned int N> constexpr size_t countof(T (&)[N]) 
note: template argument deduction/substitution failed: 

Gdy próbuję dodać specjalność:

template<typename T> constexpr 
size_t countof(T(&)[0]) 
{ 
    return 0; 
} 

nawet dostaje dziwniejsze:

error: no matching function for call to ‘countof(main()::<anonymous struct> [0])’ 
note: candidate: template<class T, long unsigned int N> constexpr size_t countof(T (&)[N]) 
note: template argument deduction/substitution failed: 
note: candidate: template<class T> constexpr size_t countof(T (&)[0]) 
note: template argument deduction/substitution failed: 
note: template argument ‘-1’ does not match ‘#‘integer_cst’ not supported by dump_decl#<declaration error>’ 

Co robię źle?

+2

Według tego odniesienia deklaracji [] array (http://en.cppreference.com/w/cpp/language/array) wyrażenie wielkość musi ocenić "do wartości większej od zera". W skrócie, tablice o zerowym rozmiarze są nieprawidłowe. –

+0

Dyskusja na temat komunikatów o błędach błędnego kompilatora! –

+0

Zamiast tego możesz użyć 'std :: array'. –

Odpowiedz

6

Zgodnie z sekcją 8.5.1 normy 2011, "Pusta lista inicjalizatorów {} nie będzie używana jako inicjator-klauzula dla tablicy nieznanych granic", z uwagą: "Składnia zapewnia pusty inicjator -lists, ale mimo to C++ nie ma tablic o zerowej długości ".

Teraz zastanawiam się, dlaczego deklaracja zostanie skompilowany ...

+0

Dozwolone w GNU C dla obiektu o zmiennej długości. https://gc.gnu.org/onlinedocs/gcc/Zero-Length.html –

+0

@jeffrycopps: wygląda na to, że potknąłem się o rozszerzenie GNU ... Co jest zabawne w przypadku makra C jak "#define countof" (tablica) (sizeof (array)/sizeof ((array) [0])) ", wszystko się kompiluje, a makro daje poprawne wyniki ... – airman

Powiązane problemy