I have a templated class foo<T>
which is specialized in many different ways.
Some of which have a lot of common code that relies on specialized functions.
For example, consider the following:
#include <iostream>
template <class T>
struct foo;
template <class T>
struct foo<T*> {
void different_function() const { std::cout << "calling from T*\n"; }
void same_function() const;
};
template <class T>
struct foo<T&> {
void different_function() const { std::cout << "calling from T&\n"; }
void same_function() const;
};
template <class T>
void foo<T>::same_function() const { // this yields an error
std::cout << "the exact same function but now ";
different_function();
}
int main() {
foo<int*> a;
a.different_function();
a.same_function();
foo<int&> b;
b.different_function();
b.same_function();
}
Each specialization of foo<T>::different_function()
is uniquely specified, and I want foo<T>::same_function()
to have generally the same code structure but is reliant on the specialization of different_function()
.
I have tried:
foo
type, but that only defines the code for the default foo
.different_function
from the foo
class is required.How could I solve this issue?
In C++23 you can use a templated explicit this
parameter in same_function
in the base class:
struct CommonBase
{
// equivalent to:
// template <typename T> void same_function(this const T &self)
void same_function(this const auto &self)
{
std::cout << "the exact same function but now ";
self.different_function();
}
};
Pre-C++23 you can use CRTP:
template <typename T>
struct CommonBase
{
void same_function() const
{
std::cout << "the exact same function but now ";
static_cast<const T &>(*this).different_function();
}
};
(Then inherit like this: struct foo<T*> : CommonBase<foo<T*>>
.)
Or you can avoid specializations in the first place, and just use if constexpr
and requires
(or std::enable_if_t
before C++20) to alter the behavior and to disable certain functions respectively.