noexcept说明符致编译失败,Clang与GCC行为不一致
问题分析:带
noexcept的函数作为参数时Clang编译失败的原因 这确实是Clang的一个已知bug,在后续版本中已经被修复了。
问题复现
先看触发问题的代码:
#include <functional> #include <utility> template <typename F> void for_each(F&&) noexcept {} template <typename F, typename T, typename... Us> void for_each(F&& f, T&& v, Us&&... us) { std::invoke(std::forward<F>(f), std::forward<T>(v)); for_each(std::forward<F>(f), std::forward<Us>(us)...); } void func(void*) noexcept {} int main() { for_each(func, nullptr); }
这段代码在GCC 8中可以正常编译通过,但在Clang 6里会抛出编译错误,核心报错是:
/opt/wandbox/clang-6.0.0/include/c++/v1/type_traits:4198:19: error: invalid application of 'sizeof' to a function type static_assert(sizeof(_Tp) > 0, "Type must be complete.");
深层原因
问题出在Clang 6的标准库实现对带noexcept限定的函数类型的完整性检查逻辑上。当std::invoke尝试处理一个带noexcept的函数引用时,Clang的std::__check_complete模板错误地将带noexcept的函数类型判定为不完整类型,从而触发了static_assert失败。而GCC的标准库实现则正确识别了带noexcept的函数类型是完整的,因此没有这个问题。
解决办法
- 临时绕过:移除
func函数上的noexcept说明符,代码就能在Clang 6中正常编译; - 彻底解决:升级到Clang 7及以上版本——这个bug在Clang 7的标准库更新中已经被修复,新版本可以正常处理带
noexcept的函数类型作为std::invoke的参数。
内容的提问来源于stack exchange,提问作者Lingxi
相关产品推荐
相关产品推荐

