c++ - 为什么这个对数组进行零初始化的模板化函数不能编译?

标签 c++ templates

我正在尝试编写一个简单的模板化函数,它将数组的所有成员初始化为零(如果数组是对象数组,则初始化为它们的默认构造状态)。这是我写的:

template<typename T, int size> inline void ClearTheArray(T[size] theArray) 
{
   for (size_t i=0; i<size; i++) theArray[i] = T();
}

...我的想法是我可以将任何数组重置为其默认构造/全零状态,如下所示:

int myArray[6] = {1,2,3,4,5,6};
ClearTheArray(myArray);
// myArray now contains all zeroes

int * somePointer = myArray;
ClearTheArray(somePointer);  // compile error: somePointer doesn't contain array length info

但是,以上代码无法编译;相反,我在形式参数列表中 theArray 的第一个实例处收到语法错误(“预期的')'”)。我在这里做错了什么?有办法做到这一点吗?

最佳答案

嗯,T[size] theArray 根本不是正确的声明语法。就像在任何其他上下文中声明数组一样,名称位于边界之前。所以 T theArray[size] 将是正确的语法。

但是这仍然不会执行您希望它执行的操作,因为数组不能按值传递并且尝试按值传递数组会导致它退化为指针。编译器必须将您的参数声明重写为简单的 T* theArray。这使得 size 无法推断,并允许您的函数接受任意指针。

要解决这些问题,您必须通过引用传递数组:

template<typename T, int size> inline void ClearTheArray(T (&theArray)[size]) 
{
   for (size_t i=0; i<size; i++) theArray[i] = T();
}

然后您的示例用法将按您预期的方式运行。

不过,重新发明轮子是没有意义的。执行此操作的标准方法是

using std::begin;
using std::end;
std::fill(begin(myArray), end(myArray), 0);
std::fill(begin(somePointer), end(somePointer), 0);  // compile error

关于c++ - 为什么这个对数组进行零初始化的模板化函数不能编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47665868/

相关文章:

c++ - 继承返回 *this 的成员函数

C++ const 与 std::pair 的正确性

c++ - 编译时已知条件的标准 if/else?

c++ - 创建通用插入函数

c++ - 未定义对静态变量 Foo::a 的引用?

c++ - jsoncpp:从代码中填充数组成员

c++ - 限制类型模板参数仅采用特定模板的实例化

c++ - 仅当从 C++11 中的 B 派生时,如何有条件地调用 B::f?

c++ - 将 boost::make_recursive_variant 与元组一起使用

C++ Qt - 打开文本文件操作失败