在static_strlen的以下实现中,为什么&和括号周围的str必要吗?

时间:2010-04-01 21:12:10

标签: c++ templates pass-by-reference

如果我将类型更改为const char str[Len],则会收到以下错误:

error: no matching function for call to ‘static_strlen(const char [5])’

我是否正确static_strlen期望一个const char 引用数组?我的理解是数组无论如何都是作为指针传递的,那么元素是否需要被引用呢?或者这种解释完全不合适?

#include <iostream>

template <size_t Len>
size_t
static_strlen(const char (&str)[Len])
{
  return Len - 1;
}

int main() {
  std::cout << static_strlen("oyez") << std::endl;
  return 0;
}

2 个答案:

答案 0 :(得分:4)

不,函数参数是对Len const字符数组的引用。这就是函数如何知道长度(假设最后一个字节是NUL终止符,因此为-1)。括号正是为了阻止它成为你的想法。

实际上在C ++中没有像引用数组这样的东西,所以即使没有parens它也不会是你认为的那样。我猜(但不确定)对parens的需求只是为了与其他类似的类型定义保持一致,例如指向数组的指针:

void fn(const char *a[3]); // parameter a is of type const char**, the 3 is ignored.
void fn(const char (*a)[3]; // parameter a is a pointer to an array of 3 const chars.

该示例还说明了为什么数组不是指针。预测以下程序的输出,然后运行它:

#include <iostream>

void fn(const char (*a)[3]) {
    std::cout << sizeof(a) << "\n" << sizeof(*a) << "\n";
}

void fn2(const char *a[3]) {
    std::cout << sizeof(a) << "\n" << sizeof(*a) << "\n";
}

int main() {
    const char a[3] = {};
    const char **b = 0;
    fn(&a);
    fn2(b);
}

#if 0 
// error: declaration of `a' as array of references
void fn3(const char & a[3]) {
    std::cout << sizeof(a) << "\n" << sizeof(*a) << "\n";
}
#endif

答案 1 :(得分:0)

这是一个可以创建函数的方法之一,使得数组的大小自动传递给函数。

static_strlen(const char (&str)[Len])

是一个函数,它接收const charLen个精确元素的数组。必须在编译时知道数组大小。即数组未通过new或malloc分配。

更具体地说,该参数是对Len元素数组的引用,而不是实际数组,这就是为什么它在传递时不会转换为指针的原因。