The short story is I am trying to have function templates and the main function in different compilation units like this (I am using g++ (GCC) 14.2.1 if it matters):
// a.cpp
template<typename T> T func(T a, T b, T c) {
return a + b + c;
}
template int func<int>(int, int, int);
template float func<float>(float, float, float);
template double func<double>(double, double, double);
// b.cpp
#include <iostream>
using namespace std;
template<typename T> T func(T a, T b, T c);
int main() {
cout << func<int>(1,2,3) << "n";
cout << func<float>(1,2,3) << "n";
cout << func<double>(1,2,3) << "n";
}
But in practice, my func
has a really long argument list. Here I have 3 arguments a
, b
, c
just as an example, but in my actual code there are dozens, whose names are also very long. So I would really like to do a simpler instantiation:
// a2.cpp
template<typename T> T func(T a, T b, T c) {
return a + b + c;
}
template func<int>;
template func<float>;
template func<double>;
Surely this won’t compile, but in principle, there is only one template argument T
. So I should have given enough information for the compile to know what function I want to instantiate.
Interestingly, I find using the following method involving function pointers works:
//a3.cpp
template<typename T> T func(T a, T b, T c) {
return a + b + c;
}
auto func_int = func<int>;
auto func_float = func<float>;
auto func_double = func<double>;
Questions:
- Is the trick in
a3.cpp
legit, as a simpler way to instantiate function templates without writing down all parameters? - If not, what could be potential problems? And is there another way to instantiate the templates without writing down parameters
a
,b
,c
?
Update 1: I don’t think the dup link answers my question. That post talks about the usage of extern template
which is to avoid repeated instantiation in different compilation units. But I am asking about a simpler syntax to do instantiation.
Update 2: Error messages for my previous code:
For a2.cpp
above, I get
a2.cpp:6:10: error: ISO C++ forbids declaration of ‘func’ with no type [-fpermissive]
6 | template func<int>;
| ^~~~~~~~~
a2.cpp:6:10: error: template-id ‘func<int>’ used as a declarator
a2.cpp:6:10: error: ‘func(T, T, T)’ is not a variable template
a2.cpp:7:10: error: ISO C++ forbids declaration of ‘func’ with no type [-fpermissive]
7 | template func<float>;
| ^~~~~~~~~~~
a2.cpp:7:10: error: template-id ‘func<float>’ used as a declarator
a2.cpp:7:10: error: ‘func(T, T, T)’ is not a variable template
a2.cpp:8:10: error: ISO C++ forbids declaration of ‘func’ with no type [-fpermissive]
8 | template func<double>;
| ^~~~~~~~~~~~
a2.cpp:8:10: error: template-id ‘func<double>’ used as a declarator
a2.cpp:8:10: error: ‘func(T, T, T)’ is not a variable template
If I remove all the template
keywords in a2.cpp
, I get
a2.cpp:6:1: error: ‘func<int>’ does not name a type
6 | func<int>;
| ^~~~~~~~~
a2.cpp:7:1: error: ‘func<float>’ does not name a type
7 | func<float>;
| ^~~~~~~~~~~
a2.cpp:8:1: error: ‘func<double>’ does not name a type
8 | func<double>;
| ^~~~~~~~~~~~
Moreover, I get the same errors even if I add extern
to b.cpp
10