Как заставить компилятор работать с аргументами класса шаблона в assigmnet? - PullRequest
2 голосов
/ 25 мая 2010

Вот код. Можно ли заставить работать последнюю строку?

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

Ответы [ 4 ]

3 голосов
/ 25 мая 2010

В 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;, это может привести к очень неприятным сюрпризам .
  2. Если вы не планируете иметь матрицы с отрицательными размерами, используйте unsigned int или, что еще более уместно, std::size_t будет лучше для аргументов шаблона.
  3. Вы не должны передавать матрицы за копию. Вместо каждого проходного эталона вместо .
  4. Multiply() можно записать operator*, что позволило бы Matrix<2,3> Three = One * Two;
  5. print вероятно должен принять поток для печати как std::ostream&. И я бы предпочел, чтобы это была свободная функция вместо функции-члена. Я бы подумал о перегрузке operator<< вместо того, чтобы назвать ее print.
2 голосов
/ 25 мая 2010

Это не возможно в C ++ 03, но C ++ 0x предлагает auto.

auto Three=Multiply(One,Two);
1 голос
/ 25 мая 2010

Нет, при использовании шаблона класса вы должны явно указать все аргументы шаблона.

Если ваш компилятор поддерживает это, вы можете использовать auto из C ++ 0x вместо:

auto Three=Multiply(One,Two);

В g ++ вы можете включить поддержку C ++ 0x, используя флаг -std=c++0x.

0 голосов
/ 25 мая 2010

Шаблоны используются во время компиляции и используются для реализации статического полиморфизма. Это означает, что вы должны знать все о своих объектах в момент компиляции кода.

Следовательно, здесь компилятор не работает, потому что ему было бы слишком сложно знать, что Three должно иметь (2,5) размеры (по крайней мере, в настоящее время общепринятый стандарт).

Если это вопрос «просто знать», тогда ОК, но в реальном коде вы, очевидно, должны использовать конструкторы для инициализации матрицы (и установки ее размеров).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...