I want to write 5 different classes, each of which has many member functions which are exactly the same, except of one, which is special for each class. Can I write this avoiding code duplication?
Regards, Aleksejs
Below is a very shortened version of my code, which throws the error:
template_test.cpp:15:35: error: invalid use of incomplete type ‘class impl_prototype<cl, 1>
#include <iostream>
using namespace std;
template <int cl, int dim>
class impl_prototype {
public:
impl_prototype() {}
int f(int x) { return cl + 2 * g(x); }
int g(int x) { return cl + 1 * x;}
};
template <int cl>
int impl_prototype<cl, 1>::g(int x) { return cl + 3 * x; }
int main ()
{
impl_prototype<0, 0> test_0;
impl_prototype<0, 1> test_1;
cout << test_0.f(5) << " " << test_0.g(5) << std::endl;
cout << test_1.f(5) << " " << test_1.g(5) << std::endl;
return 0;
}
Member functions of class templates can be explicitly specialized but not partially specialized.
Just make a helper function object that you can partially specialize:
#include <iostream>
using namespace std;
template<int cl, int dim>
struct g_impl
{
int operator()(int x) { return cl + 1 * x;}
};
template<int cl>
struct g_impl<cl, 1>
{
int operator()(int x) { return cl + 3 * x; }
};
and then call that helper (the tempoary function object will optimized away):
template <int cl, int dim>
class impl_prototype
{
public:
impl_prototype() {}
int f(int x) { return cl + 2 * g(x); }
int g(int x) { return g_impl<cl, dim>()(x); }
};
int main ()
{
impl_prototype<0, 0> test_0;
impl_prototype<0, 1> test_1;
cout << test_0.f(5) << " " << test_0.g(5) << std::endl;
cout << test_1.f(5) << " " << test_1.g(5) << std::endl;
return 0;
}
Live Example
An other method is Tag dispatching, something like:
template <int cl, int dim>
class impl_prototype
{
int g(int x, std::integral_constant<int, 1>) { return cl + 3 * x; }
template <int I>
int g(int x, std::integral_constant<int, I>) { return cl + 1 * x; }
public:
int f(int x) { return cl + 2 * g(x); }
int g(int x) { return g(x, std::integral_constant<int, dim>());}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With