How to make compiler work out template class arguments at assigmnet?
Here's the code. Is it possible to make last line work?
#include<iostream>
using namespace std;
template <int X, i开发者_运维百科nt 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;
}
In C++11 you can use auto
to do that:
auto Three=Multiply(One,Two);
In current C++ you cannot do this.
One way to avoid having to spell out the type's name is to move the code dealing with Three
into a function template:
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;
}
Edit: A few more notes to your code.
- Be careful with
using namespace std;
, it can lead to very nasty surprises. - Unless you plan to have matrices with negative dimensions, using
unsigned int
or, even more appropriate,std::size_t
would be better for the template arguments. - You shouldn't pass matrices per copy. Pass per const reference instead.
Multiply()
could be spelledoperator*
, which would allowMatrix<2,3> Three = One * Two;
print
should probably take the stream to print to asstd::ostream&
. And I'd prefer it to be a free function instead of a member function. I would contemplate overloadingoperator<<
instead of naming itprint
.
This wont be possible in C++03 but C++0x offers auto
.
auto Three=Multiply(One,Two);
No, when using a class template, you have to specify all template arguments explicitly.
If your compiler supports it, you can use auto
from C++0x instead:
auto Three=Multiply(One,Two);
In g++, you can enable C++0x support using the -std=c++0x
flag.
Templates are used at compilation time and are used to implement static polymorphism. This means you should know everything about your objects at the moment your code is being compiled.
Hence, here the compiler fails, because this would be too hard for it to know that Three
should have (2,5)
dimensions (at least at currently common standard).
If this is a question for "just-to-know", then OK, but in real code you should obviously use constructors to initialize matrix (and set it's dimensions).
精彩评论