2010-05-25 52 views
2

這是代碼。是否有可能使最後一行工作?如何讓編譯器在assigmnet處理模板類參數?

#include<iostream> 
using namespace std; 

template <int X, int Y> 
class Matrix 
{ 
    int matrix[X][Y]; 
    int x,y; 
    public: 
    Matrix() : x(X), y(Y) {} 
    void print() { cout << "x: " << x << " y: " << y << endl; } 
}; 

template < int a, int b, int c> 
Matrix<a,c> Multiply (Matrix<a,b>, Matrix<b,c>) 
{ 
    Matrix<a,c> tmp; 
    return tmp; 
} 

int main() 
{ 
    Matrix<2,3> One; 
    One.print(); 
    Matrix<3,5> Two; 
    (Multiply(One,Two)).print(); // this works perfect 
    Matrix Three=Multiply(One,Two); // !! THIS DOESNT WORK 
    return 0; 
} 

回答

3

在C++ 11可以使用auto做到這一點:

auto Three=Multiply(One,Two); 

在當前的C++,你不能這樣做。以避免拼出類型的名稱

一種方法是處理Three代碼移動到一個函數模板:

template< int a, int b > 
void do_something_with_it(const Matrix<a,b>& One, const Matrix<a,b>& Two) 
{ 
    Matrix<a,b> Three = Multiply(One,Two); 
    // ... 
} 

int main() 
{ 
    Matrix<2,3> One; 
    One.print(); 
    Matrix<3,5> Two; 
    do_something_with_it(One,Two); 
    return 0; 
} 

編輯:一些更多的音符你的代碼。

  1. 小心using namespace std;,它可能導致very nasty surprises
  2. 除非你計劃使用負值的矩陣,使用unsigned int或更合適的std::size_t對於模板參數會更好。
  3. 您不應該傳遞每個副本的矩陣。 Pass per const reference instead
  4. Multiply()可以拼寫operator*,這將允許Matrix<2,3> Three = One * Two;
  5. print或許應該採取以打印爲std::ostream&流。我更喜歡它是一個自由函數而不是成員函數。我會考慮超載operator<<而不是命名它print
+0

我同意您的所有代碼評論註釋。請注意1有爭議。 Herb Sutter被認爲更喜歡那種風格。我看到他的推理。他認爲只有'使用名字空間標準'纔可以,'其他所有人都被禁止。也就是說,標題中的全局「使用」總是一個壞主意。再次,我同意1. – 2010-05-25 14:47:14

+1

順便說一下,C++ 0x可能會在2012年才能最終確定,因此C++ 11與C++ 0x一樣具有誤導性。我更喜歡C++ 0x,因爲它更爲人所知,沒有人期望在2009年發佈。 – 2010-05-25 14:52:14

+0

@Caspin:這不是頭文件(有一個main()函數實現),但仍然如此。如果Sutter確實說過使用名稱空間標準,那麼他並不孤單,基本上所有介紹性的C++書籍和教程都使用它 - 這讓我感到非常傷心。它會導致如我所鏈接的問題中的那種微妙的錯誤。 [我前幾天廣泛討論這個問題。](http://stackoverflow.com/questions/2879555/2880136#2880136) – sbi 2010-05-25 14:57:04

2

這在C++ 03中是不可能的,但C++ 0x提供了auto

auto Three=Multiply(One,Two); 
0

模板用於編譯時,用於實現靜態多態性。這意味着在編譯代碼的時候,您應該知道有關對象的所有信息。

因此,在這裏編譯器會失敗,因爲如果知道Three應具有(2,5)維度(至少在當前通用標準),那麼這太難了。

如果這是一個「只是知道」的問題,那麼確定,但在真實的代碼中,你應該明顯地使用構造函數來初始化矩陣(並設置它的尺寸)。

1

不,使用類模板時,必須明確指定所有模板參數。

如果你的編譯器支持它,你可以使用auto從的C++ 0x代替:

auto Three=Multiply(One,Two); 

在G ++,你可以啓用C++使用-std=c++0x標誌0X支持。

相關問題