3

我是 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 '\0'. */
    }
};

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

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

4

5 回答 5

4

它的意思是“引用 const char 数组”。原因是,如果你像

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

根据“数组参数弃用规则”,您将丢失大小信息,主要是因为指针不保存数组大小信息。(AKA 标准是这样说的。)所以你必须通过引用而不是指针值来传递。

[] 之前的括号是必需的,因为 [] 将优先于 &,因此为了使 & 优先,它需要像

 T (&a)[s]
于 2012-07-26T12:33:52.510 回答
2
const char (&array)[ArrayLength]

ArrayLength是对类型对象数组的引用char

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

在我看来,函数模板将被实例化为带有特定 ArrayLength 参数的东西。

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

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

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

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

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

于 2012-07-26T12:32:55.633 回答
2

这是通过引用传递数组的语法(因为在 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
}
于 2012-07-26T12:36:27.993 回答
0

给定的代码是一个很好的教训:起初,它想传递一个数组,所以不能按值传递,然后通过引用 (&) 传递,然后它通过安全传递它的 const 字传递它。你知道 C/C++ 对数组有限制,所以这段代码的程序员定义了一个数组长度的模板,并解决了这个问题。

于 2012-07-26T12:38:55.300 回答
0

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

“append”的模板版本(您包含)调用了一个带有 2 个参数的重载:一个指向 char 的指针和一个 count(您没有包含这个)。

所以你可能有一个像这样的数组:

const char my_string[] = "hi";

您将像这样使用“附加”成员函数:

my_string_buffer_object.append(my_string);

并且会自动检测 my_string 的长度,将 ArrayLength 参数设置为 my_string 的长度。然后调用更详细的“append”版本,并自动为您填写字符串长度。

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

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

于 2012-07-26T13:17:04.320 回答