C 数组大小作为函数?

发布于 2024-10-30 12:45:21 字数 831 浏览 4 评论 0原文

可能的重复:
这个“数组大小”模板函数如何工作?

在 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 */ }

模板?超载?魔法?

Possible Duplicate:
How does this “size of array” template function work?

Is there any possibility to implement NARR without a macro in C++ (C++0x)?

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

A simple function is not possible, because then the [] loses its size-information and becomes just another poiner:

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

Templates? Overloading? Magic?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不交电费瞎发啥光 2024-11-06 12:45:21

在 C++ 中这是可能的:

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

与宏解决方案相比,它的优点是,如果您尝试传递指向此的指针,编译器将发出令人讨厌的错误消息。

It is possible in C++:

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

The advantage of this over the macro solution is that the compiler will cough up a nasty error message if you try to pass a pointer to this.

君勿笑 2024-11-06 12:45:21

在 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 将调用。但是,如果他们提供的东西适用于基于范围的 for,但不适用于您的代码,那么您将不得不争论谁应该更改。

In C++0x:

#include <iterator>

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

Also you can use std::begin(data) if you like, for symmetry or genericness[*]. And possibly you can use an initializer list instead of an array anyway...

[*] Although for full genericness, you should probably do:

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

The reason is that the new "range-based for loop" syntax is equivalent to using begin and end without qualification, but with std as an associated namespace for ADL. So as with std::swap, authors of types might provide begin and end functions that are intended to be found via ADL. They probably ought to provide begin() and end() member functions instead, which std::begin and std::end will call. But if they provide something that works with ranged-based for, and doesn't work with your code, then you'll have to have an argument who should change.

心碎无痕… 2024-11-06 12:45:21

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

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

I can't test this right now, because I've been away for a while and the latest GCC 4.6 just refused to compile, but constexpr should make short work of the question. Of course, it's better to sidestep this issue using Steve's suggestion.

template< typename T, size_t N >
constexpr size_t narr( T const (&)[ N ] )
    { return N; }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文