需要帮助理解此C++模板的语法

Need help understanding the syntax of this C++ template

本文关键字:语法 C++ 帮助 助理      更新时间:2023-10-16

我是C++模板的新手,遇到了这些C++模板相关的代码,但无法理解它们的含义:

class StringBuffer
{
    CharBuffer cb;
..
    template <size_t ArrayLength>
    bool append(const char (&array)[ArrayLength]) {
        return cb.append(array, array + ArrayLength - 1); /* No trailing ''. */
    }
};

bool append(const char(&array)[ArrayLength])是什么意思?在我看来,函数模板将被实例化为某个具有特定ArrayLength的参数。但是,难道我们不能在函数的参数列表中指定数组长度吗?还有const char(&array)是什么意思?它不应该是类似于const char&(不带括号)?

我正在阅读David Vandvooorde/Nicolai M.Josuttis的《C++模板完整指南》一书,该书的哪一部分涵盖了上述语法?

意思是"对const char数组的引用"。原因是如果你像一样通过

template <int S>
void f(T a[s]){}

根据"数组参数弃用规则",您将丢失大小信息,主要是因为指针不包含数组大小信息。(AKA标准就是这么说的。)因此,您将不得不通过引用而不是通过指针值进行传递。

[]之前的括号是必需的,因为[]将优先于&,所以为了使&优先,它需要像一样完成

 T (&a)[s]
const char (&array)[ArrayLength]

是对类型为CCD_ 2的CCD_。

如果没有括号,它将是一个引用数组,这是不允许的。如果没有&,它将是一个(作为函数参数)衰减为指针的数组,从而丢失有关数组大小的信息。

在我看来,函数模板将被实例化为某个具有特定ArrayLength的参数。

没错。数组长度在编译时是已知的,这将实例化一个可以使用该编译时值的函数。

但是,难道我们不能在函数的参数列表中指定数组长度吗?

是的,您可以提供长度作为一个额外的函数参数;但这将是一个运行时值,并且有已知的方法来验证它是否正确。该模板确保模板参数实际上是数组的大小。

这本书的哪一部分涵盖了上述语法?

我没有那本书,但看看目录,我建议看4.2(非类型函数模板参数)和11(模板参数推导)。

这是通过引用传递数组的语法(因为在C++中数组不能通过值传递):

void foo(const char (&array)[10]) { ... } // We can pass an array of lenth 10

现在在混合中抛出一个模板参数,而不是10。编译器在编译时知道数组的大小,并可以用正确的值实例化模板。

template<size_t N>
void foo(const char (&array)[N])
{
    // use N, it'll be whatever the size of the array you instantiate the template with is
}

此语法将根据静态分配的数组参数的大小设置模板参数。

模板化版本的"append"(您包含的)调用一个重载,该重载包含两个参数:一个指向char的指针和一个count(您没有包含)。

所以你可能有一个数组,比如:

const char my_string[] = "hi";

您可以使用这样的"附加"成员函数:

my_string_buffer_object.append(my_string);

my_string的长度将自动检测,将ArrayLength参数设置为my_string长度。然后调用一个更详细的"append"版本,并自动为您填充字符串长度。

基本上,这个版本的"accept"包装了另一个版本。它允许您传递一个数组作为唯一的参数,并使用模板参数的信息自动填充长度。

如果使用此语法,请记住,这些数组长度参数计算的是元素,而不是对象大小(sizeof会告诉您数组的大小)。对于char,这些是相同的,但具有较大元素类型的数组将生成一个小于其sizeof的模板数组长度参数。

给定的代码是一堂很好的课:一开始,它想传递一个数组,所以不能通过值传递,然后通过refence(&)传递,然后它通过安全传递的const字传递。你知道C/C++在数组中有局限性,所以这段代码的程序员定义了一个数组长度的模板,并解决了这个问题。