2010-05-25 51 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支持。

相关问题