I have a several classes with templated member functions and a predefined list of types they will be used with (Wandbox link:
// main.cpp:
#include "class.h"
int main(int argc, char** argv) {
A a;
a.foo(5);
a.foo(5.);
B b;
//b.bar(1,2,3,4); b.bar(1,2,3.,4);
return 0;
}
// class.h
#pragma once
struct A {
template<typename T> void foo(T x);
};
struct B {
template<typename T> void bar(int p1, int p2, T x, int p3);
};
// class.cpp
#include <iostream>
#include "class.h"
template<typename T> void A::foo(T x) {
std::cout << x << std::endl;
}
// explicit, but very verbose
// template void A::foo(int);
// ...
template<typename T> void ignore(T fn) {/* Use fn? */}
template<class Class>
void instantiate(Class) {
// List all types the function should be instantiated for here
ignore(&Class::template foo<int>);
ignore(&Class::template foo<double>);
}
// works, instantiates A::foo<int> and A::foo<double>
template void instantiate(A);
// How to pass B::foo and additional parameters?
// template void instantiate(B);
Typing out every combination of member function and type to be instantiated with works, but it has several drawbacks:
- it's tedious
- the whole function signature with every parameter has to typed out, and
- function signature changes have to be made in several places
- adding a single type to the list has to be made for every member function
My workaround as above works on most older compilers I've tested (C++03 compatibility would be a huge plus), but I'm not sure if a smart compiler would be allowed to remove the unused parameter and the function instantiations.
For regular functions, there are workarounds, but as far as I understood, they don't work for member functions.
How can I change my instantiate
function to also accept a member function and additional parameters?