开发者

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.

  1. Be careful with using namespace std;, it can lead to very nasty surprises.
  2. 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.
  3. You shouldn't pass matrices per copy. Pass per const reference instead.
  4. Multiply() could be spelled operator*, which would allow Matrix<2,3> Three = One * Two;
  5. print should probably take the stream to print to as std::ostream&. And I'd prefer it to be a free function instead of a member function. I would contemplate overloading operator<< instead of naming it print.


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).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜