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“未使用”类诊断的启发式似乎根本不检查每个实例化,而是检查未实例化的模板本身。
我自己也遇到过类似的问题,特别是当依赖模板函数中的构造函数来产生副作用时(对于 RAII 等)。当 Clang 需要知道传递的模板参数以确定所使用的构造函数时,它会天真地将构造函数视为纯构造函数,并将构造变量标记为未使用 (Wunused-variable
),但如果构造函数可以在不实例化模板的情况下确定变量,那么它不会将变量标记为未使用,因为它可以确定构造函数会产生可观察到的副作用。
就您而言,由于您的模板很可能位于头文件中,因此无论是否标记为 static
都没有区别。使用type traits库“可能的实现”作为指导,并避免将这些模板值标记为静态
以避免诊断。
关于C++ Clang 发出有关未使用模板变量的警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66986718/