How can a templated function be invoked, that is defined in another translation unit?
I found so far solutions that require explicit instantiation of all used combinations. For more complex scenarios it is almost impossible to maintain manually. So I wonder if there is a neat way to achieve that without explicit instantiation?
A simple scenario could look like this:
// a.h
template <typename D> struct base {/*...*/};
struct a : base<a> {/*...*/};
struct b : base<b> {/*...*/};
struct c : base<c> {/*...*/};
// main.cpp
#include "a.h"
#include "b.h"
int main () {
DoSomething<a>(1,2,3);
DoSomething<a>('h','e','l','l','o');
DoSomething<b>(4,'a',5.0);
DoSomething<c>('f','o','o',6.0f);
}
// b.h
// forward declaration
template <typename T, typename... Args>
void DoSomething (Args...);
// b.cpp
#include "b.h"
#include "a.h"
template <typename T, typename... Args>
void DoSomething (Args... args) {
// do stuff
}
Use case is the launch of a templated CUDA kernel launcher, where b.h
and b.cpp
act as CUDA header & definition. CUDA nvcc compiler/linker come with a few more restrictions, that appear to me not to be relevant for the minimal example above (no auto
keyword, no module
support), so tried to provide an example as generic as possible.