Is it possible to check at compile time if a function pointer points to a function with external linkage?
What I'm imagining is a type traits-style template that returns whether or not a function pointer has external linkage.
void linked() {}
void test() {
// Returns true, since `linked` will have external linkage.
bool fn = has_external_linkage<linked>::value;
auto unlinked = []() {};
constexpr auto *unlinked_ptr = +unlinked;
// Returns false, since function pointers to lambdas
// have no external linkage.
bool lambda = has_external_linkage<unlinked_ptr>::value;
}
Reasoning
What I really care about is whether it's valid to pass a function pointer as a template parameter. The following code fails in GCC, stating that fn does not have external linkage.
template <typename FnType, FnType fn>
void call() {
fn();
}
int main(int argc, char** argv) {
auto lambda = []() {};
constexpr *lambda_ptr = +lambda;
call<decltype(lambda_ptr), lambda_ptr>();
return 0;
}
If I swap out lambda_ptr for a constexpr pointer to a regular function, the code compiles fine, since the function will have external linkage.
Essentially, I'd like to be able to avoid the runtime overhead of sending a function pointer whenever it's possible to encode it as a template parameter. However, I'd still like to be able to send the function pointer when it can't be a template parameter. Hence, I'd like to construct something like a has_external_linkage template so I can choose the appropriate path.