1

我知道这个问题被问了很多次,我不是在问怎么做,因为我是在编译时这样做的。我的问题是它是如何工作的,因为那是我不明白的。

当将 a 传递char[]给函数时,它会丢失其信息并变成char*,因此我们无法在编译时使用模板获取字符数组的大小,所以我尝试并传递了字符串本身并且它起作用了:

template <int N> inline int arr_len(const char (&)[N]) { return N - 1; }

#define STR "this is an example!"

const char *str_ptr = STR;

int main()
{
  int array_size = arr_len(STR);
}

我用 VC++ 2008、Intel C++ 12 和 GCC 4.7 测试了这段代码,它可以工作。

通过传递字符串本身,编译器将其视为const char[]-至少我认为是这样-并且他能够获得字符串大小,这怎么可能?

4

3 回答 3

4

字符串字面量类型是数组,而不是指针。因此,当您将它直接传递给通过引用获取数组的函数时,它不会衰减为指针。

于 2012-05-04T20:20:29.903 回答
2

那是因为 STR 是在编译器启动之前被替换的宏。

它将它替换为“XXXX”,这是一个字符串文字(不是数组)。

要使其正常工作,请执行以下操作:

char const  str_ptr[] = "XXX YYY";
              //  ^^^^    Compiler works out size

int main()
{
    int array_size = arr_len(str_ptr);
                         //  ^^^^^^^ pass in an object that has a type.
};
于 2012-05-04T20:19:58.833 回答
0

在 C++ 中,当函数的参数类型被暂时标识为数组时,参数类型被“调整”为指向数组元素类型的指针。

因此,当您编写时:void foo(char c[])编译器有效地将其重写为void foo(char *c). 然后当你传递一个数组时:

char x[10];
foo(x);

C++ 发现void foo(char *c)并看到它可以将您的char []参数转换为 achar *并调用该函数,而这正是它所做的。

但是,这种对函数类型的调整只有在写入的参数类型是数组时才会发生。对数组的引用不是数组,因此在声明函数时不会执行等效调整void bar(char (&c)[10])

回答您的问题所需的第二点是字符串文字的类型是 const char 数组。当您直接在函数调用中编写字符串文字时,使用 C++ 的函数会const char (&)[N]看到它可以传递对数组的引用,而不是执行“数组 -> 指向第一个元素的指针”转换。这就是它的作用,模板类型推导为字符串的大小找到正确的数字。

于 2012-05-04T20:28:07.503 回答