c++ - 在编译时检查函数是否有外部链接

标签 c++ templates 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;
}

推理

我真正关心的是将函数指针作为模板参数传递是否有效。以下代码在 GCC 中失败,表明 fn 没有外部链接。

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;
}

如果我将 lambda_ptr 替换为指向常规函数的 constexpr 指针,则代码可以正常编译,因为该函数将具有外部链接。

基本上,只要有可能将函数指针编码为模板参数,我就希望能够避免发送函数指针的运行时开销。但是,我仍然希望能够在不能作为模板参数时发送函数指针。因此,我想构建类似 has_external_linkage 模板的东西,这样我就可以选择合适的路径。

最佳答案

恕我直言,使用函数地址作为模板参数是 UB,你不应该使用它。原因是,对于不同平台上的不同编译器,函数地址在执行时间上可能是未知的。

它在具有 VM 的体系结构上工作并将静态虚拟地址分配给本地函数并不意味着什么,因为 UB 允许以任何方式工作,甚至是您期望它工作的方式;)

相反,正如在其他一些问题中提出的那样,您可以按值传递函数对象。

关于c++ - 在编译时检查函数是否有外部链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56745282/

相关文章:

c++ - 告诉 clang-format 忽略编译指示

C++ 余弦问题

excel - 创建时在 Excel 模板中插入当前日期

c++ - 静态 vector 的大小

c++ - 为什么不同 block 中相同命名的外部局部变量在 C++ 中的编译器之间获得不同的链接?

c++ - 依赖于同一个静态链接库的可执行文件和共享库

c++ - 是否将 namespace 范围的文件本地 (.cpp) 常量放置在匿名 namespace 中

c++ - C++:函数 “no matching function for call to”错误

c++ - 将 Matlab 句柄类转换为 C++

c++ - 编译时的类型特化