Reputation: 441
I am defining class A
that can take function as template argument. Class B
inherits class A
. However, there are errors B: use of class template requires template argument list
and multiple other errors. I am thinking that declaration of class B
has gone wrong. However, I am not using any template for class B
. Can someone comment?
#include <iostream>
void f_global()
{
std::cout << "top level function\n";
}
template<typename F>
class A
{
public:
F f1;
A(F fun1) : f1(fun1) {}
void fa();
};
template<typename F>
void A<F> :: fa()
{
std::cout << "From A<F>::fa()\n";
f1();
}
template<typename F>
class B : public A<F> //error
{
public:
void fb();
};
void B::fb() //error
{
std::cout << "From B::fb()\n";
A::f1(); //Can access f1()?
}
int main()
{
A obja(f_global); //error?
obja.fa();
B objb;
objb.fb();
}
Upvotes: 1
Views: 78
Reputation: 3018
First of all, it is often useful to explain what you are trying to achieve. There are many very smart people here which would come up with solutions to your problem which have absolutely nothing to do with yours.
Now, I've tried to guess what you wanted to achieve. Since you call fa
from fb
, I assumed B
is a template
. If not, then at least fb
should be a templated function. However, since you don't pass the function to execute as argument to fb
, I finally guessed that your class B
is intented to be a template
.
So, your global function is fine:
void f_global()
{
std::cout << "top level function\n\n";
}
Your class A
is ok, but for clearness, I'd use F
for the function type and F*
for the function pointer (*), and I would also store the function
as a private
member. However, to respect the code in your question, I'll leave it as a public
member.
EDIT (*)
As @Phil1970 pointed out, F
is more general than F*
as it would work with lambdas and std::function
.
template <typename F>
class A
{
public:
A(F fun) : _f {fun} {}
void fa() { std::cout << "From A<F>::fa()\n"; _f(); }
F _f;
};
As you correctly figured out, there is a problem with your class B
. First of all, if template <typename F> B
inherits from template <typename F> A
, you should be able to construct an object of type A<F>
from within the constructor of B<F>
. In other words, B<F>
should be able to construct A<F>
, and therefore, you should pass the function f_global
to the constructor of class B<F>
.
template <typename F>
class B : public A<F>
{
public:
B(F* fun) : A<F>(fun) {}
void fb() { std::cout << "From B::fb()\n"; A<F>::_f(); }
void fb1() { std::cout << "From B::fb1()\n"; this->template _f(); }
using A<F>::_f;
void fb2() { std::cout << "From B::fb2()\n"; _f(); }
};
I added functions fb1
and fb2
to show you how to call the callable _f
member using template deduction and using the keyword using
.
Upvotes: 2