成员数组的 C++ countof 实现

C++ countof Implementation for Member Arrays

我正在尝试使用 C++ 模板创建与 Visual Studio _countof 宏等效的内容。以下是我提出的定义:

template<typename T, size_t N>
inline constexpr size_t countof(T const (&array)[N]) {
    return N;
}
template<typename T, typename U, size_t N>
inline constexpr size_t countof(T const (U::&array)[N]) {
    return N;
}

上面的第二个声明试图修复以下代码,该代码在 g++ 9 中生成编译时错误,消息为:"error: invalid use of non-static data member ‘foo::bar’":

struct foo {
    int const bar[4];
    static_assert(countof(bar) == 4);
};

但是,当我添加第二个定义并将断言更改为使用 foo::bar 时,g++ 生成错误:"error: ‘template constexpr const size_t countof’ conflicts with a previous declaration".

我可以更改代码以使用指向成员的指针(而不是对成员的引用),但这似乎是不必要的。有谁知道制作 countof 版本的方法,该版本仅在传递数组时编译,并且以合理的方式对自由变量数组和成员变量数组起作用?

问题是 bar 的用法在 static_assert(countof(bar) == 4); 中无效,您需要 foo 的实例并获取成员数组 bar 以传递给 countof.

I can change the code to use pointer-to-member (instead of reference to member), but that seems like it should be unnecessary.

您可以更改代码以使用指向成员的指针。例如

template<typename T, typename U, size_t N>
inline constexpr size_t countof(T const (U::*array)[N]) {
    return N;
}

然后

static_assert(countof(&foo::bar) == 4);

LIVE

或更改 countof 以指定类型而不是将数组传递给它。

template<typename T>
struct count_of{};
template<typename T, size_t N>
struct count_of<T const [N]> {
    constexpr static size_t value = N;
};
template<typename T>
inline constexpr size_t countof() {
    return count_of<T>::value;
}

然后

static_assert(countof<decltype(foo::bar)>() == 4);

LIVE

我想不出没有宏的方法,但是 this post 提供了一种同时获得类型安全的方法(确保传递给 countof 的参数是一个数组)并支持免费和成员数组。结果代码是:

template<typename T, size_t N>
char (&COUNTOF_REQUIRES_ARRAY_ARGUMENT(T (&array)[N]))[N];

#define countof(x) sizeof(COUNTOF_REQUIRES_ARRAY_ARGUMENT(x))