Newbie: template question

M

marcus

What is wrong with the following code. I get "illegal use of this type
as an expression". Isn't it possible to use methods of class <S> (is
it just pure data classes, without methods that can be used).

class A{
public:
func1();
func2();
private:
B<A> myVar;
}
A::func1()
{
// some code
}
A::func2()
{
myVar.foo()
}

template <class S>
class B{
public:
int foo();
}

template <class S>
int B<S>::foo()
{
S.func1();
}
 
V

Victor Bazarov

marcus said:
What is wrong with the following code.

Plenty. See below.
I get "illegal use of this type
as an expression". Isn't it possible to use methods of class <S> (is
it just pure data classes, without methods that can be used).

class A{
public:
func1();
^
Return value type is missing here.
^
Return value type is missing here.
private:
B<A> myVar;
^
'B' is undefined here.
^
A semicolon missing here.
A::func1()
^
Return value type is missing here.
{
// some code
}
A::func2()

^
Return value type is missing here.
{
myVar.foo()

'B said:
}

template <class S>
class B{
public:
int foo();
}
^
A semicolon is missing here.
template <class S>
int B<S>::foo()
{
S.func1();

'S' is a type. You cannot use the dot notation with a type, you need
an instance (an object or a reference) to use the dot.

Non-void function has no 'return' statement. Undefined behaviour is
expected.

Enough?

V
 
M

marcus

Plenty. See below. ^
Return value type is missing here.
^
Return value type is missing here.
^
'B' is undefined here.
^
A semicolon missing here.
^
Return value type is missing here.
^
Return value type is missing here.

'B<A>' is undefined. Use of undefined type.
^
A semicolon is missing here.
'S' is a type. You cannot use the dot notation with a type, you need
an instance (an object or a reference) to use the dot.

Non-void function has no 'return' statement. Undefined behaviour is
expected.

V

OK i confess, I was in a hurry and I have not compiled this code, I
wrote it directly into the NG.
For completeness, there should also have been a main method invoking
the func2() method.
You commented the important problem aswell though and that is my
attempt to invoke S.func1()from within the foo method.

Can you be more specific about S beeing a type and how I am to do a
S.func1() call. I use the class keyword in "template <class S>", so
new to this as I am I expected S to be a class and not a type.

So my question here is not really about missing semicolons or such,
but about how to use the methods of a class that is beeing used in a
template class/method (see my attempt S.func1()). I want to be able to
do a call like this, so how do I do it?

thanx
 
V

Victor Bazarov

marcus said:
[...]
Can you be more specific about S beeing a type and how I am to do a
S.func1() call. I use the class keyword in "template <class S>", so
new to this as I am I expected S to be a class and not a type.

So my question here is not really about missing semicolons or such,
but about how to use the methods of a class that is beeing used in a
template class/method (see my attempt S.func1()). I want to be able to
do a call like this, so how do I do it?

Here is your problem:
---------------------------------------
template<class S> struct A
{
void foo();
};

struct HasFunc1
{
void func1();
};

template<class S> void A<S>::foo()
{
S.func1(); /// ???????????????????????
}

int main()
{
A<HasFunc1> a;
a.foo();
}
---------------------------------------

I don't know the solution to your problem. But the reason this is not
correct code is simple: non-static member functions (like func1 here)
_require_an_instance_of_their_class_ in order to be called. The example
of that is in the 'main' function: to call 'foo' you need the 'a'.

So, in the A<S>::foo, if you want to call 'func1', you need _an_instance_
of the 'S' class. One possible solution is for 'foo' to have an argument
of type S (or S&), like this:

template<class S> void A<S>::foo(S& rs)
{
rs.func1();
}

Another possible solution is to have a member of class S in A and use it
to call 'func1'. There are probably variations on the theme, and which
one is right depends on your design, if you have it.

One thing I need to mention. You may have noticed that in my explanation
of the reason I did say "non-static". So, another _possible_ solution is
to assume that 'func1' is a static member of S. Then the syntax to call
it becomes slightly different:

S::func1();

but other static member limitations apply. Again, which one is the real
solution to your problem is impossible for me to divine.

V
 
M

marcus

Thanks a lot, I think your help will become very helpful. Now I just
gonna go through what you have written once more to see if I got
everything.

Thanks again!


Victor Bazarov said:
marcus said:
[...]
Can you be more specific about S beeing a type and how I am to do a
S.func1() call. I use the class keyword in "template <class S>", so
new to this as I am I expected S to be a class and not a type.

So my question here is not really about missing semicolons or such,
but about how to use the methods of a class that is beeing used in a
template class/method (see my attempt S.func1()). I want to be able to
do a call like this, so how do I do it?

Here is your problem:
---------------------------------------
template<class S> struct A
{
void foo();
};

struct HasFunc1
{
void func1();
};

template<class S> void A<S>::foo()
{
S.func1(); /// ???????????????????????
}

int main()
{
A<HasFunc1> a;
a.foo();
}
---------------------------------------

I don't know the solution to your problem. But the reason this is not
correct code is simple: non-static member functions (like func1 here)
_require_an_instance_of_their_class_ in order to be called. The example
of that is in the 'main' function: to call 'foo' you need the 'a'.

So, in the A<S>::foo, if you want to call 'func1', you need _an_instance_
of the 'S' class. One possible solution is for 'foo' to have an argument
of type S (or S&), like this:

template<class S> void A<S>::foo(S& rs)
{
rs.func1();
}

Another possible solution is to have a member of class S in A and use it
to call 'func1'. There are probably variations on the theme, and which
one is right depends on your design, if you have it.

One thing I need to mention. You may have noticed that in my explanation
of the reason I did say "non-static". So, another _possible_ solution is
to assume that 'func1' is a static member of S. Then the syntax to call
it becomes slightly different:

S::func1();

but other static member limitations apply. Again, which one is the real
solution to your problem is impossible for me to divine.

V
 

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,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top