Istnieje kilka dobrych powodów, aby woląLiczba tablic, które nie używają odr?
#include <cstdlib>
template<typename T, std::size_t N>
constexpr std::size_t ARRAY_COUNT_FUNC(T (&arr)[N]) { return N; }
zamiast
#define ARRAY_COUNT_MACRO(arr) (sizeof(arr)/sizeof(*arr))
Jedną ważną różnicą jest to, że gdy wskaźnik (nie tablica) jest przekazywana do ARRAY_COUNT_MACRO
, dyskretnie zwraca odpowiedź niepomocny, ale przechodząc ten sam argument ARRAY_COUNT_FUNC
spowoduje błąd kompilatora wskazując na błąd.
Ale makro ma jedną zaletę: jego argument jest unevaluated.
#include <utility>
struct S {
int member_array[5];
};
// OK:
std::size_t count1 = ARRAY_COUNT_MACRO(std::declval<S&>().member_array);
// ERROR: std::declval is odr-used!
std::size_t count2 = ARRAY_COUNT_FUNC(std::declval<S&>().member_array);
Czy istnieje inne podejście z zalet zarówno razem? I. e., Coś, co powoduje błąd kompilacji, jeśli argument nie jest tablicą i nie odr-używa jego argumentu.
Pan tylko wie, jak dawno temu pomysł został pierwszy wykluły, ale [Microsoft wykorzystuje zasadniczo ten sam algorytm] (http://blogs.msdn.com/b/the1/archive/2004/05 /07/128242.aspx) za '_countof (ar)' makro i ma co najmniej od '04. Szansa jest prawdopodobnie * bezszustowa * zerwana z kimś innym. – WhozCraig