#include <iostream>
template<class T> T CreateArray(T a, int n)
{
a = new T [n]; // mistake: double* = double**
return a;
}
int main()
{
double* a;
int n = 5;
a = CreateArray(a,n);
return 0;
}
我可以使用模板和新分配内存吗?我的错误是什么?
答案 0 :(得分:3)
你的代码有些错误。首先,你可以做一些像你想做的事情,但你应该这样写:
template<class T> T* CreateArray(int n)
{
T* a = new T [n];
return a;
}
int main()
{
double* a;
int n = 5;
a = CreateArray<double>(n);
return 0;
}
请注意,您不必传递a
数组(它将在CreateArray
内复制,并且其更改将在main
内不可见)。另请注意,您将模板定义为返回指针T*
,这是main()
a
所期望的。
答案 1 :(得分:3)
所以其他人已经解释了为什么你的代码不起作用以及如何改进它。
现在我将展示如何仍然获取以下代码进行编译 - 并正常工作:
double* a = CreateArray(5);
int* b = CreateArray(7);
正如已经提到的,问题在于C ++不仅仅从返回类型推断出模板参数。
您可以通过使上述函数返回一个简单的代理对象来规避此限制。代理对象只有一个操作:(隐式)转换为T*
。这是实际分配的地方。
因此CreateArray
函数非常简单(不模板):
CreateArrayProxy CreateArray(std::size_t num_elements) {
return CreateArrayProxy(num_elements);
}
至于代理:
struct CreateArrayProxy {
std::size_t num_elements;
CreateArrayProxy(std::size_t num_elements) : num_elements(num_elements) { }
template <typename T>
operator T*() const {
return new T[num_elements];
}
};
简单π。
现在,您应该使用此代码吗?不,可能不是。它没有直接分配的真正优势。但这是一个有用的成语。
答案 2 :(得分:2)
您希望接受指针到您要分配的类型:
template<class T> T* CreateArray(T* a, int n)
{
a = new T [n];
return a;
}
这应该可以解决问题。
答案 3 :(得分:2)
我更喜欢保持空指针值为NULL。
#include <iostream>
template<class T> bool CreateArray(T * &a, int n)
{
if ( a != 0 )
return false;
a = new T [n];
return true;
}
int main()
{
double* a = 0;
int n = 5;
CreateArray(a,n);
return 0;
}
vector
也可能是一个很好的解决方案。我认为这是更好的一个,因为你不会使内存泄漏。
#include <vector>
int main()
{
std::vector<double> a;
int n = 5;
a.resize(n);
return 0;
}