Originally, I had a C++ class A
with a templated class member function member()
. Because member()
is a performance hotspot, it has multiple internal implementations. Depending on some runtime conditions, the public function member()
selects one of them by instantiating the templated member function memberImpl()
.
class A
{
template <typename T>
void memberImpl()
{
}
void member()
{
// if (a) {
memberImpl<float>();
//}
// else {
memberImpl<int>();
// }
}
};
It worked, but I noticed that the same check is necessary for multiple member functions, thus, instead of repeating the same check in each member function, I thought it would be a good idea to create a new second-order template dispatch
that accepts the original first-order template as a template template for doing the check and instantiating the underlying templates.
class A
{
template <typename T>
void memberImpl()
{
}
template <template <typename> typename Impl>
void dispatch()
{
// if (a) {
Impl<float>();
//}
// else {
Impl<int>();
// }
}
void member()
{
dispatch<memberImpl>();
}
};
I believe this substitution is possible during compile-time, and it’s within the capability of C++ templates. Unfortunately it’s an invalid C++ program according to GCC and clang:
demo.cpp: In member function ‘void A::member()’:
demo.cpp:23:37: error: no matching function for call to ‘A::dispatch<((A*)this)->A::memberImpl>()’
23 | dispatch<memberImpl>();
| ~~~~~~~~~~~~~~~~~~~~^~
demo.cpp:11:14: note: candidate: ‘template<template<class> class Impl> void A::dispatch()’
11 | void dispatch()
| ^~~~~~~~
demo.cpp:11:14: note: template argument deduction/substitution failed:
demo.cpp:23:37: error: type/value mismatch at argument 1 in template parameter list for ‘template<template<class> class Impl> void A::dispatch()’
23 | dispatch<memberImpl>();
| ~~~~~~~~~~~~~~~~~~~~^~
demo.cpp:23:37: note: expected a class template, got ‘((A*)this)->A::memberImpl’
It seems that I believe memberImpl
is a template, but the compiler says it’s actually a function. I tried to add the keyword template
to different places but was unsuccessful.
What is the correct C++ syntax to achieve my goal?