C-Array的大小作为函数?

时间:2011-04-05 07:47:19

标签: c++ sizeof c++11

  

可能重复:
  How does this “size of array” template function work?

在C ++(C ++ 0x)中没有宏的情况下是否有可能实现NARR

const static pair<string,int> data[] = {
    {"Montag",1}, {"Dienstag",2}, {"Mittwoch",3}, {"Donnerstag",4},
    {"Freitag",5}, {"Samstag",6}, {"Sonntag",7}
};
#define NARR(A) (sizeof(A)/sizeof(*A))
const static map<string,int> german_weekdays(data, data+NARR(data));

一个简单的函数是不可能的,因为[]失去了它的大小信息,变成了另一个诗人:

size_t narr(sometype arr[]) { /* won't work */ }

模板?超载?魔法?

3 个答案:

答案 0 :(得分:9)

可以在C ++中使用:

template< typename T, std::size_t Size >
std::size_t size(const T (&)[Size])
{
  return Size;
}

这对宏解决方案的优势在于,如果您尝试将指针传递给此,编译器将会发出令人讨厌的错误消息。

答案 1 :(得分:4)

在C ++ 0x中:

#include <iterator>

const static map<string,int> german_weekdays(data, std::end(data));

如果您愿意,也可以使用std::begin(data)来表示对称性或通用性[*]。也许你可以使用初始化列表而不是数组......

[*]虽然完整的一般性,你应该这样做:

using std::begin;
using std::end;
begin(data), end(data);

原因是新的“基于范围的for循环”语法等同于使用beginend而没有限定,但使用std作为ADL的关联命名空间。与std::swap一样,类型的作者可能会提供旨在通过ADL找到的beginend函数。他们可能应该提供begin()end()成员函数,std::beginstd::end会调用。但是如果它们提供的东西适用于基于范围的,并且不能与你的代码一起使用,那么你将不得不有一个应该改变的论点。

答案 2 :(得分:2)

我现在无法测试,因为我已经离开了一段时间,最新的GCC 4.6只是拒绝编译,但是constexpr应该简短地解决这个问题。当然,最好使用史蒂夫的建议来回避这个问题。

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