数组计数没有使用?

asc*_*ler 6 c++

有几个很好的理由可以选择

#include <cstdlib>

template<typename T, std::size_t N>
constexpr std::size_t ARRAY_COUNT_FUNC(T (&arr)[N]) { return N; }
Run Code Online (Sandbox Code Playgroud)

而不是

#define ARRAY_COUNT_MACRO(arr) (sizeof(arr)/sizeof(*arr))
Run Code Online (Sandbox Code Playgroud)

一个重要的区别是,当一个指针(不是一个数组)被传递给ARRAY_COUNT_MACRO它时,它会静默地返回一个无用的答案,但传递相同的参数ARRAY_COUNT_FUNC会导致编译错误指出错误.

但宏确实有一个优势:它的论点没有评估.

#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);
Run Code Online (Sandbox Code Playgroud)

还有另一种方法可以同时获益吗?例如,如果参数不是数组,则会导致编译错误,并且不会使用其参数.

BoB*_*ish 6

如此处所述,无耻地从Chromium项目中扯下.

#include <utility>
#include <cstdlib>

template<typename T, std::size_t N>
constexpr std::size_t ARRAY_COUNT_FUNC(T (&arr)[N]) { return N; }

#define ARRAY_COUNT_MACRO(arr) (sizeof(arr)/sizeof(*arr))

// Template for typesafey goodness.
template <typename T, size_t N>
char (&ArraySizeHelper(T (&array)[N]))[N];
// sizeof to avoid actually calling the function.
#define arraysize(array) (sizeof(ArraySizeHelper(array)))

struct S {
    int member_array[5];
};

int main()
{

    // 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);

    // OK:
    std::size_t count2 = arraysize(std::declval<S&>().member_array);

    // ERROR:
    // int * p;
    // std::size_t count3 = arraysize(p);
}
Run Code Online (Sandbox Code Playgroud)

  • Lord只知道多久以前这个想法是第一次出现,但[微软使用的算法基本相同](http://blogs.msdn.com/b/the1/archive/2004/05/07/128242.aspx) `_countof(ar)`宏,至少已经'04了.他们可能会毫不犹豫地将其从其他人身上撕下来. (3认同)