当特化位于不同标头时,C++ 模板函数特化错误

can*_*las 3 c++ templates function specialization

标头中cnvt.h有:

template <typename t_to, typename t_from> std::optional<t_to> cnvt(t_from);
Run Code Online (Sandbox Code Playgroud)

在 header 中int.h,我们有:

#include "cnvt.h" 

template <>
std::optional<uint8_t> cnvt<uint8_t, const char *>(const char *) {
  // actual code replaced for simplicity
  return {};
}
Run Code Online (Sandbox Code Playgroud)

clang-tidy报道称,事实如此

clang 报告“int.h:: 不直接使用包含的标头 cvnt.h(可用修复) 不直接使用包含的标头 cvnt.h(可用修复)

如果删除#include "cnvt.h",它会报告

int.h:9:24:没有函数模板与函数模板专业化“cnvt”匹配

我搜索了 StackOverflow,关于函数模板专业化的帖子没有帮助。

Tar*_*ama 5

该警告来自 clangd 而不是 clang-tidy。对于您编写的代码,您确实需要cnvt.h包含标头。clangd 只是没有看到您需要该标头中的主要模板来进行专业化。

\n

来自clangd 文档

\n
\n

I\xe2\x80\x99m 以一种棘手的方式使用符号(例如通过模板),但标头被标记为未使用

\n

有些类型的用途是分析无法找到的。

\n

抑制警告// IWYU pragma: keep

\n
\n

因此,您应该能够通过// IWYU pragma: keep在 include for 之后添加来抑制警告cnvt.h

\n

但是,如果可以的话,我建议完全回避问题并使用函数重载而不是模板专业化:

\n
std::optional<uint8_t> cnvt(const char *) {\n  // actual code replaced for simplicity\n  return {};\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这使得主模板不再需要在int.h标题中可见。

\n

  • 关于建议,“t_to”不可推导,因此用法类似于“cnvt&lt;std::uint8_t&gt;(some_text)”,与您的版本不兼容。 (2认同)