我是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追加(const char(&amp; array)[ArrayLength])是什么意思?在我看来,函数模板将被实例化为带有特定ArrayLength参数的东西。但是不是我们不能在函数的参数列表中指定数组长度吗? const char(&amp; array)的含义是什么?不应该像 const char&amp; (没有括号)吗?
我正在阅读由David Vandevoorde / Nicolai M.Josuttis撰写的 C ++模板完整指南一书,本书的哪一部分涵盖了上述语法?
答案 0 :(得分:4)
表示“引用const char数组”。 原因是如果你像
那样通过template <int S>
void f(T a[s]){}
根据“数组参数弃用规则”,您将丢失大小信息,主要是因为指针不包含数组大小信息。 (AKA标准这样说。) 所以你必须通过引用传递而不是通过指针值传递。
[]之前的括号是必需的,因为[]将优先于&amp;,所以为了使&amp;优先考虑需要像
那样完成 T (&a)[s]
答案 1 :(得分:2)
const char (&array)[ArrayLength]
是对ArrayLength
类型的char
个对象的引用。
如果没有括号,它将是一个引用数组,这是不允许的。如果没有&
,它将是一个数组(作为函数参数)衰减到指针,丢失有关数组大小的信息。
在我看来,函数模板将被实例化为带有特定ArrayLength参数的东西。
没错。数组长度在编译时是已知的,这将实例化一个可以使用该编译时值的函数。
但是,我们不能在函数的参数列表中指定数组长度吗?
是的,您可以提供长度作为额外的功能参数;但这将是一个运行时值,并且有知道验证它是否正确的方法。模板确保模板参数确实是数组的大小。
本书的哪一部分涵盖了上述语法?
我没有那本书,但是,看看table of contents我建议看看4.2(非类型函数模板参数)和11(模板参数演绎)这类事情。
答案 2 :(得分:2)
这是通过引用传递数组的语法(因为数组不能通过C ++中的值传递):
void foo(const char (&array)[10]) { ... } // We can pass an array of lenth 10
现在在mix中抛出一个模板参数而不是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
}
答案 3 :(得分:0)
给定的代码是一个很好的教训: 首先,它想传递一个数组,所以不能通过值传递,然后通过引用(&amp;)传递,然后通过安全传递它的const字传递它。 你知道C / C ++在数组中有局限性,所以这段代码的程序员为Array的长度定义了一个模板,并解决了这个问题。
答案 4 :(得分:0)
此语法将根据静态分配的数组参数的大小设置模板参数。
“append”的模板化版本(包括你)调用一个带有2个参数的重载:指向char和count的指针(你没有包含它)。
所以你可能有一个像:
这样的数组const char my_string[] = "hi";
您可以使用“append”成员函数,如下所示:
my_string_buffer_object.append(my_string);
将自动检测my_string的长度,将ArrayLength参数设置为my_string的长度。然后调用更详细的“append”版本,并自动填充字符串长度。
基本上,这个版本的“accept”包装了另一个版本。它允许您将数组作为唯一参数传递,使用模板参数的信息自动填充长度。
如果使用此语法,请记住这些数组长度参数计算元素而不是对象大小(sizeof会告诉您有关数组的信息)。对于char,它们是相同的,但具有较大尺寸元素类型的数组将产生小于其sizeof的模板数组长度参数。