I have been developing an application using wxWidgets (detail, but not specific to the problem). I have a class called MyPanel, and in it, I have a timer that I start and stop as needed. I use the timer for a number of different purposes, although only one of the purposes can be active at a time. To do this, I have two methods:
StartTimer and StopTimer, both of which must be passed the timer handler to bind/unbind when the timer is started or stopped. To simplify the code, I use an alias for the handler type. Here is the declaration:
using TimerHandler = void (MyPanel::*) (wxTimerEvent&);
class MyBasePanel : public wxGLCanvas
{
...
std::unique_ptr<ShaderProgram> m_program;
...
}
class MyPanel : public MyBasePanel
{
...
void StartTimer(TimerHandler handler);
...
}
So with this, everything compiles and runs. Now the problem. I want to have multiple classes derived from MyBasePanel, each using a different ShaderProgram class and different handlers. So, I changed my class declarations as follows:
template <typename T>
class MyBasePanel : public wxGLCanvas
{
...
std::unique_ptr<T> m_program;
...
}
template <typename T>
class MyPanel : public MyBasePanel<T>
{
...
}
Now when I attempt to compile, Visual Studio gives this error on the alias:
'MyPanel': use of class template requires template argument list
OK, so I changed the alias to:
template <typename T>
using TimerHandler = void (MyPanel<T>::*) (wxTimerEvent&)
and the StartTimer (and StopTimer) method declarations to:
void StartTimer(TimerHandler<T> handler);
Now Visual Studio spits out:
'MyPanel<T>::StartTimer': unable to match function definition to an existing declaration
note: see declaration of 'MyPanel<T>::StartTimer'
note: definition
'void MyPanel<T>:StartTimer(void (__cdecl MyPanel<T>::* )(wxTimerEvent &))'
existing declarations
'void MyPanel<T>:StartTimer(void (__cdecl MyPanel<T>::* )(wxTimerEvent &))'
Note that the declarations are the same. Some investigating indicates that the C++ standard does not really allow combining aliasing and templating in this way.
I have come up with one potential solution to this problem that I think will work. Instead of passing in the handler to the StartTimer and StopTimer methods, pass in a flag, then test the flag and bind/unbind the matching handler. I haven't tried this, but I think it will work. My concern is that this seems kludgy; there should be a more esthetically pleasing solution.