在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 */ }
模板?超载?魔法?
答案 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循环”语法等同于使用begin
和end
而没有限定,但使用std
作为ADL的关联命名空间。与std::swap
一样,类型的作者可能会提供旨在通过ADL找到的begin
和end
函数。他们可能应该提供begin()
和end()
成员函数,std::begin
和std::end
会调用。但是如果它们提供的东西适用于基于范围的,并且不能与你的代码一起使用,那么你将不得不有一个应该改变的论点。
答案 2 :(得分:2)
我现在无法测试,因为我已经离开了一段时间,最新的GCC 4.6只是拒绝编译,但是constexpr
应该简短地解决这个问题。当然,最好使用史蒂夫的建议来回避这个问题。
template< typename T, size_t N >
constexpr size_t narr( T const (&)[ N ] )
{ return N; }