compile error: invalid use of template-name 'Row' without an argument list

Hi,
Can anyone help figure out this compile error?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>

template< int N >			//Non-type Template Arguments
class Row
{
	private:
		int samples[ N ];	//array of samples
	public:
		void scan()
		{
			for (int i=0; i<N; i++)
			{
				samples[i] = i;
				std::cout << samples[i];
			}
		}
};

class Matrix
{
	private:
		Row* row1;
	public:
		Matrix(Row* r): row1(r) {}
};

const int N=2;
Row< N > row;
Matrix mat(&row);

int main()
{
	row.scan();
}

template.cpp:22:3: error: invalid use of template-name 'Row' without an argument list
   Row* row1;
   ^
template.cpp:24:13: error: expected ')' before '*' token
   Matrix(Row* r): row1(r) {}
             ^
template.cpp:29:16: error: no matching function for call to 'Matrix::Matrix(Row< 2>*)'
 Matrix mat(&row);
                ^
template.cpp:29:16: note: candidates are:
template.cpp:19:7: note: Matrix::Matrix()
 class Matrix
       ^
template.cpp:19:7: note:   candidate expects 0 arguments, 1 provided
template.cpp:19:7: note: Matrix::Matrix(const Matrix&)
template.cpp:19:7: note:   no known conversion for argument 1 from 'Row<2>*' to 'const Matrix&'

Thank you.

Same but without composition compiles fine:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

template< int N >			//Non-type Template Arguments, number of samples
class Row
{
	private:
		int samples[ N ];	//array of samples
	public:
		void scan()
		{
			for (int i=0; i<N; i++)
			{
				samples[i] = i;
				std::cout << samples[i];
			}
		}
};

const int N=2;
Row< N > row;

int main()
{
	row.scan();
}


Same but without template compiles fine:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>

const int N=2;
class Row
{
	private:
		int samples[ N ];	//array of samples
	public:
		void scan()
		{
			for (int i=0; i<N; i++)
			{
				samples[i] = i;
				std::cout << samples[i];
			}
		}
};

class Matrix
{
	private:
		Row* row1;
	public:
		Matrix(Row* r): row1(r) {}
};

Row row;
Matrix mat(&row);

int main()
{
	row.scan();
}
Row is a templated class. Because of that Row<1> and Row<2> are two distinct types. They differs as much as int* and char

So compiler do not know answer to main question: which Row is referred on line 22?

You can:
1) explicitely provide template argument list to Row making row1 of concrete class: Row<2>* row1;. Not very useful
2) Make Matrix templated too so Matrix<2> would contain Row<2>. Drawbacks: Matrices with different sized rows will become of distinct types.
3) Use type erasure and templated constructor:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>

class Row_base
{
  public:
    virtual void scan() = 0;
};

template< int N >			//Non-type Template Arguments
class Row : public Row_base
{
  private:
    int samples[ N ];	//array of samples
  public:
    virtual void scan()
    {
        for (int i=0; i<N; i++)	{
            samples[i] = i;
            std::cout << samples[i];
        }
    }
};


class Matrix
{
  private:
    Row_base* row1;
  public:
    template<int N>
    Matrix(Row<N>* r): row1(r) {}
};

const int N=2;
Row< N > row;
Matrix mat(&row);

int main()
{
    row.scan();
}
Last edited on
Well done MiiNiPaa!
That took pulling together several concepts: polymorphism, composition, templates, and type erasure pattern.
Thank you for showing me the way.
Topic archived. No new replies allowed.