2011-04-01 77 views
2
#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

你面臨什麼問題? – sharptooth 2011-04-01 12:48:24

+0

爲什麼你想自己創建一個數組,當std :: vector會爲你做? – 2011-04-01 17:16:00

+0

我想創建一個n * n * n的數組。所有這些都是一個特例。 – ObiSan 2011-04-02 00:24:09

回答

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所期望的。

+0

您錯過了'CreateArray (n)'。 – ybungalobill 2011-04-01 13:02:28

+0

嗯,是的,修復。我不確定在這種情況下是否需要這樣做(編譯器可以推斷出它),但我會將其添加完成。 – 2011-04-01 13:03:11

+2

@Diego:編譯器不要使用返回類型進行模板參數推導。 – ybungalobill 2011-04-01 13:04:58

2

你要接受指針到要分配類型:

template<class T> T* CreateArray(T* a, int n) 
{ 
    a = new T [n]; 
    return a; 
} 

這應該做的伎倆。

+0

'template T * CreateArray(T *&a,int n) { a = new T [n]; return a; }' - 小修改。 – Naszta 2011-04-01 12:54:06

+1

@Naszta:誰說他想修改論點? – ybungalobill 2011-04-01 12:55:38

+0

ybungalobill。他或她顯然試圖修改一個,但正如他或她注意到的那樣,它在該方法內部不起作用,因此它將其返回並直接在'main()'中分配。這就是爲什麼使用對指針的引用可能會更好他或她明白。 – 2011-04-01 12:57:15

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; 
} 
+2

你可能更喜歡,但現在它是一個完全不同的程序,具有不同的語義。 – 2011-04-01 13:03:49

+0

有趣的解決方案,但編譯器做的表達「T *&」,並認爲變量的乘法,不? – ObiSan 2011-04-01 13:10:11

+0

@ObiSan:MS編譯器剛接受它。它是一個指針的參考。 – Naszta 2011-04-01 13:15:20

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]; 
    } 
}; 

容易爲π。

現在,你應該使用這個代碼?不,可能不是。它不提供直接分配的真正優勢。但這是一個有用的習語。

+0

即分配內存時更好地分配模板? – ObiSan 2011-04-01 13:26:24

+0

@ObiSan並非一般,但上面的代碼可能是意想不到的。但除此之外,你通常應該避免**完全分配內存。 C++的優勢在於你大多數時候不必擔心內存管理。對於數組,解決方案很簡單:始終使用'std :: vector'而不是動態內存。 – 2011-04-01 13:34:02