我知道这个问题多次问过,我不会问怎么做,因为我是在编译时这样做的。我的问题是它是如何工作的,因为这是我不理解的。
当将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,英特尔C ++ 12和GCC 4.7测试了这段代码,它可以运行。
通过传递字符串本身,编译器将其视为const char[]
- 至少我认为 - 并且他能够获得字符串大小,这怎么可能?
答案 0 :(得分:3)
字符串文字类型是一个数组,而不是指针。因此,当您将其直接传递给通过引用获取数组的函数时,它不会衰减为指针。
答案 1 :(得分:1)
这是因为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.
};
答案 2 :(得分:0)
在C ++中,当函数的参数类型暂时被识别为数组时,参数类型被调整为&#39;是一个指向数组元素类型的指针。
因此,当您编写:void foo(char c[])
时,编译器会将其有效地重写为void foo(char *c)
。然后当你传递一个数组时:
char x[10];
foo(x);
C ++找到void foo(char *c)
并发现它可以将您的char []
参数转换为char *
并调用该函数,这正是它所做的。
但是,只有当写入的参数类型是数组时,才会对函数类型进行此调整。对数组的引用不是数组,因此在声明函数void bar(char (&c)[10])
时不会执行等效调整。
回答你的问题需要的第二点是字符串文字的类型是一个const char数组。当您在函数调用中直接编写字符串文字时,使用const char (&)[N]
C ++的函数可以看到它可以传递对数组的引用,而不是执行&#34;数组 - &gt;指向第一个元素的指针&#34;转换。这就是它的作用,模板类型推导找到了正确的字符串大小的数字。