C++ Clang 发出关于未使用的模板变量的警告

C++ Clang emit warning about unused template variable

C++ Clang 发出关于未使用的模板变量的警告

考虑一个未使用的模板变量定义,例如这个:

template <typename T, typename = void>
struct is_complete : std::false_type {};
template <typename T>
struct is_complete<T, std::void_t<decltype(sizeof(T))>>
    : std::true_type {};
template <typename T>
constexpr static inline auto is_complete_v = is_complete<T>::value;

在这里,Clang 发出关于未使用 is_complete_v 变量的警告,这对我来说似乎是错误的。
如果未使用,为什么要实例化这种变量符号?也许我漏掉了一点。

warning: unused variable 'is_complete_v' [-Wunused-const-variable]
    static inline constexpr auto is_complete_v = is_complete_v<T>::value;
           

情况是,GCC 等其他编译器不会发出任何警告。
哪个 IMOO 有意义,因为符号未解析。

我可以修复我正在使用的所有代码库:

template <typename T>
#if __clang__
[[maybe_unused]]
#endif
constexpr static inline auto is_complete_v = is_complete<T>::value;

或者通过禁用 -Wunused-const-variable,

但我想知道是否:

Clang“未使用”class 诊断的试探法似乎根本不检查每个实例化,而是检查未实例化的模板本身。

我自己也遇到过类似的问题,特别是在依赖模板函数中的构造函数产生副作用时(对于 RAII 等)。当 Clang 需要知道传递的模板参数以确定使用的构造函数时,它天真地将构造函数视为纯构造函数并将构造的变量标记为未使用 (Wunused-variable),但如果可以在不实例化模板,则它不会将变量标记为未使用,因为它可以确定构造函数会产生可观察到的副作用。

在您的情况下,由于您的模板很可能无论如何都在头文件中,因此它是否标记为 static 没有区别。使用 type traits 库“可能的实现”作为指南,避免将这些模板值标记为 static 以避免诊断。