gpt4 book ai didi

c++ - 如何在编译期间计算数组大小(不接受指针)?

转载 作者:可可西里 更新时间:2023-11-01 16:32:33 25 4
gpt4 key购买 nike

给定一个数组 a,我希望 countof(a) 产生数组中元素的数量作为编译时常量。如果我有一个指针 p,我希望 countof(p) 不编译。这看起来应该是 (1) 简单明了并且 (2) 通常包含在 SO 中,但是 (1) 我无法让它工作,并且 (2) 搜索 SO 没有发现任何东西。

这是我的尝试。

#include <cstddef>
#include <type_traits>

template<typename T, std::size_t n,
typename = typename std::enable_if<std::is_array<T>::value>::type>
constexpr std::size_t countof(T (&)[n]) { return n; }

template<typename T,
typename = typename std::enable_if<std::is_pointer<T>::value>::type>
void countof(T*) = delete;

int main()
{
int a[10];
auto asize = countof(a); // should compile
static_assert(countof(a) == 10,
"countof(a) != 10!");

int *p;
auto psize = countof(p); // shouldn't compile
}

帮忙吗?

最佳答案

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

通过了您的两项测试。无法将 int* 转换为 T const(&)[N],因此不需要禁用代码。

要扩展它,我们应该添加:

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

我什至可能想将其扩展为为容器调用 size()。虽然通常不会是编译时,但统一性可能会有用:

for(int i=0; i<countof(c); ++i) {
// code
}

或者你有什么。

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

template<typename T> struct type_sink { typedef void type; };
template<typename T> using TypeSink = typename type_sink<T>::type;
template<typename T, typename=void>
struct has_size : std::false_type {};
template<typename T>
struct has_size<T, TypeSink< decltype( std::declval<T>().size() ) > >:
std::true_type
{};
template<bool b, typename T=void>
using EnableIf = typename std::enable_if<b,T>::type;

template<typename T>
constexpr
EnableIf<has_size<T const&>::value,std::size_t>
countof( T const& t ) {
return t.size();
}
// This is optional. It returns `void`, because there
// is no need to pretend it returns `std::size_t`:
template<typename T>
constexpr
EnableIf<std::is_pointer<T>::value>
countof( T const& t ) = delete;

非常冗长,但为我们提供了 std::array 支持、std::initializer_list 支持、C 风格数组支持——所有这些都在编译时——在运行时,标准容器和字符串都是 countofable 的。如果传递指针,系统会告知您调用的函数是deleteed。

在那种情况下,我试图创建一个 static_assert,但遇到了任何 template 必须具有有效特化的解析规则的问题。我怀疑将整个问题路由到具有基于 SFINAE 的特化的 countof_impl 类中可能会解决该问题。

=deletestatic_assert 解决方案的缺点是指针实际上存在重载。如果您没有那个,那么根本就没有有效的函数可以调用,它接受一个指针:这更接近事实。

关于c++ - 如何在编译期间计算数组大小(不接受指针)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21207430/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com