need non-default constructor in a class to make a member

M

Mark

I have a problem with a template class defined:

// start matrix.h file
template <class T> class Matrix
{
public:

Matrix() { // default constructor }

Matrix(const Subscript rows, const Subscript cols)
{
// constructs matrix but does special processing depending
// on values of rows/cols
}
private:
.....

};

// end matrix.h file


// start other class file:
const Subscript foo = 3;
const Subscript bar = 4;

class Other
{

private:

Matrix <double> M(foo, bar); // doesn't compile
Matrix <double> M; // compiles fine

};

g++ won't let this compile because of a "foo is not a type" error.
I think the compiler thinks that "M" is a private function prototype.
How can I force the compiler to realize M is just a "Matrix<double>" constructed
with the non-default constructor?

Mark
 
V

Victor Bazarov

Mark said:
I have a problem with a template class defined:

// start matrix.h file
template <class T> class Matrix
{
public:

Matrix() { // default constructor }

Matrix(const Subscript rows, const Subscript cols)
{
// constructs matrix but does special processing depending
// on values of rows/cols
}
private:
.....

};

// end matrix.h file


// start other class file:
const Subscript foo = 3;
const Subscript bar = 4;

class Other
{

private:

Matrix <double> M(foo, bar); // doesn't compile

Initialisations belong in the constructor initialiser list.
Matrix <double> M; // compiles fine

};

g++ won't let this compile because of a "foo is not a type" error.
I think the compiler thinks that "M" is a private function prototype.

Yes, it does.
How can I force the compiler to realize M is just a "Matrix<double>"
constructed with the non-default constructor?

Put the proper initialisation of 'M' in the 'Other's constructor's
initialiser list.

V
 
A

Andre Kostur

I have a problem with a template class defined:

// start matrix.h file
template <class T> class Matrix
{
public:

Matrix() { // default constructor }

Matrix(const Subscript rows, const Subscript cols)
{
// constructs matrix but does special processing depending
// on values of rows/cols
}
private:
.....

};

// end matrix.h file


// start other class file:
const Subscript foo = 3;
const Subscript bar = 4;

class Other
{

private:

Matrix <double> M(foo, bar); // doesn't compile
Matrix <double> M; // compiles fine

};

g++ won't let this compile because of a "foo is not a type" error.
I think the compiler thinks that "M" is a private function prototype.
How can I force the compiler to realize M is just a "Matrix<double>"
constructed with the non-default constructor?

Because you don't initialize member variables at the point of
declaration, you initialize them during the constructor of the enclosing
class:

const Subscript foo = 3;
const Subscript bar = 4;

class Other
{
public
Other() : M(foo, bar) {};

private:
Matrix<double> M;
};
 
M

Mark

Victor said:
Initialisations belong in the constructor initialiser list.

I knew that, I was just using the const Subscripts to show
what the two arguments were and to try to keep the example
simple. What I'm really doing is to
be able to instantiatate multiple different "Matrix"
instantiations with several different row and column
values where they are declared in the h files.

So the problem is I can't use an initialization list because
that's obviously fixed for those values.
So is there any way to pass different row and column values from
the header file? I think it might be possible to do this via
templates but I'm not clear on the syntax:

Matrix <double, row, cols> M;

and in my Matrix template have a <T, Subscript, Subscript> section
in addition to the usual <T> where the former case uses the
non-default constructor.

BTW, I can't just go grab an expression
template library because this code base is too big and there'd be too
many lines to change. So I'm trying to slightly adapt the
code to occasionally use the non-default constructor (this will save memory
for my object pools) but usually use the default constructor (it's designed to
be faster for doing processing in function calls on the stack.)

Anyway, I think I see what the problem is now.
 
J

James Kanze

I knew that, I was just using the const Subscripts to show
what the two arguments were and to try to keep the example
simple. What I'm really doing is to
be able to instantiatate multiple different "Matrix"
instantiations with several different row and column
values where they are declared in the h files.

I'm not sure I understand; I don't see a problem. An
initializer can be any expression you want. You can't have more
than one data member with the same name, of course, but if your
class has two Matrix<double> (say m1 and m2), there's absolutely
no problem with:

Other::Other()
: m1( foo, bar )
, m2() // optional...
{
}
So the problem is I can't use an initialization list because
that's obviously fixed for those values.

No. It can contain any expression you want.
So is there any way to pass different row and column values from
the header file? I think it might be possible to do this via
templates but I'm not clear on the syntax:
Matrix <double, row, cols> M;

That's a different thing entirely. There's no problem with
defining non-type parameters, and using them, but then the
arguments must be constant expressions.
and in my Matrix template have a <T, Subscript, Subscript> section
in addition to the usual <T> where the former case uses the
non-default constructor.

You cannot overload class templates. If the Matrix template has
three parameters, it has three parameters (although you can
provide default values).
 
V

Victor Bazarov

James said:
That's a different thing entirely. There's no problem with
defining non-type parameters, and using them, but then the
arguments must be constant expressions.


You cannot overload class templates. If the Matrix template has
three parameters, it has three parameters (although you can
provide default values).

In addition to providing default values it is possible to "narrow
down" the set of resulting types by partially specialising class
templates. Just a thought.

V
 
C

Colander

I have a problem with a template class defined:

// start matrix.h file
template <class T> class Matrix
{
public:

Matrix() { // default constructor }

Matrix(const Subscript rows, const Subscript cols)
{
// constructs matrix but does special processing depending
// on values of rows/cols
}
private:
.....

};

// end matrix.h file

// start other class file:
const Subscript foo = 3;
const Subscript bar = 4;

class Other
{

private:

Matrix <double> M(foo, bar); // doesn't compile
Matrix <double> M; // compiles fine

};

g++ won't let this compile because of a "foo is not a type" error.
I think the compiler thinks that "M" is a private function prototype.
How can I force the compiler to realize M is just a "Matrix<double>" constructed
with the non-default constructor?

not tried....
Matrix <double> M = Matrix <double>(foo, bar);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top