If you have something like this:
#include <iostream>
template<typename T> class A
{
public:
void func()
{
T::func();
}
};
class B : public A<B>
{
public:
virtual void func()
{
std::cout << "into func";
}
};
class C : public B
{
};
int main()
{
C c;
c.func();
return 0;
}
Is func() dynamically dispatched?
How could you implement class A such that if B has a virtual override, that it is dynamically dispatched, but statically dispatched if B doesn’t?
Edit: My code didn’t compile? Sorry guys. I’m kinda ill right now. My new code also doesn’t compile, but that’s part of the question. Also, this question is for me, not the faq.
#include <iostream>
template<typename T> class A
{
public:
void func()
{
T::func();
}
};
class B : public A<B>
{
public:
virtual void func()
{
std::cout << "in B::func()\n";
}
};
class C : public B
{
public:
virtual void func() {
std::cout << "in C::func()\n";
}
};
class D : public A<D> {
void func() {
std::cout << "in D::func()\n";
}
};
class E : public D {
void func() {
std::cout << "in E::func()\n";
}
};
int main()
{
C c;
c.func();
A<B>& ref = c;
ref.func(); // Invokes dynamic lookup, as B declared itself virtual
A<D>* ptr = new E;
ptr->func(); // Calls D::func statically as D did not declare itself virtual
std::cin.get();
return 0;
}
visual studio 2010\projects\temp\temp\main.cpp(8): error C2352: 'B::func' : illegal call of non-static member function
visual studio 2010\projects\temp\temp\main.cpp(15) : see declaration of 'B::func'
visual studio 2010\projects\temp\temp\main.cpp(7) : while compiling class template member function 'void A<T>::func(void)'
with
[
T=B
]
visual studio 2010\projects\temp\temp\main.cpp(13) : see reference to class template instantiation 'A<T>' being compiled
with
[
T=B
]
I’m not sure I understand what you’re asking, but it appears you are missing the essential CRTP cast:
If T does not declare its own func, this will be infinite recursion as self.func will find A<T>::func. This is true even if a derived class of T (e.g. DV below) declares its own func but T does not.
Test with different final overrider to show dispatch works as advertised: