问题描述
有问题的代码是
#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);
}
It compiles on gcc 8, but fails on clang 6 with the following error:
/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.");
^~~~~~~~~~~
/opt/wandbox/clang-6.0.0/include/c++/v1/type_traits:4203:15: note: in instantiation of template class 'std::__1::__check_complete<void (void *) noexcept>' requested here
: private __check_complete<_Tp>
^
/opt/wandbox/clang-6.0.0/include/c++/v1/type_traits:4496:15: note: in instantiation of template class 'std::__1::__check_complete<void (&)(void *) noexcept>' requested here
: private __check_complete<_Fp>
^
/opt/wandbox/clang-6.0.0/include/c++/v1/type_traits:4559:9: note: in instantiation of template class 'std::__1::__invokable_r<void, void (&)(void *) noexcept, nullptr_t &&>' requested here
__invokable<_Fp, _Args...>::value,
^
/opt/wandbox/clang-6.0.0/include/c++/v1/type_traits:4568:14: note: in instantiation of template class 'std::__1::__invoke_of<void (&)(void *) noexcept, nullptr_t &&>' requested here
: public __invoke_of<_Fp, _Args...>
^
/opt/wandbox/clang-6.0.0/include/c++/v1/type_traits:4573:22: note: in instantiation of template class 'std::__1::result_of<void (&(nullptr_t &&))(void *) noexcept>' requested here
template <class _Tp> using result_of_t = typename result_of<_Tp>::type;
^
/opt/wandbox/clang-6.0.0/include/c++/v1/functional:2349:1: note: in instantiation of template type alias 'result_of_t' requested here
result_of_t<_Fn&&(_Args&&...)>
^
prog.cc:9:3: note: while substituting deduced template arguments into function template 'invoke' [with _Fn = void (&)(void *) noexcept, _Args = <nullptr_t>]
std::invoke(std::forward<F>(f), std::forward<T>(v));
^
prog.cc:16:3: note: in instantiation of function template specialization 'for_each<void (&)(void *) noexcept, nullptr_t>' requested here
for_each(func, nullptr);
^
1 error generated.
删除func()
上的noexcept
说明符
void func(void*) /* noexcept */ {}
然后编译.我不明白这一点.这是编译器错误吗?
It then compiles. I don't get this. Is this a compiler bug?
推荐答案
好. libc ++无法处理标记为noexcept
的函数.当函数为noexcept
时,它的机器似乎由于某种原因而失败,并且采用了错误的部分专业化(针对对象而不是针对函数).
Well no. libc++ fails to handle noexcept
marked functions. It looks like its machinery fails for some reason when the function is noexcept
and it takes the wrong partial specialization (the one for objects not for functions).
因为您不能使用函数的sizeof
,所以clang正确地抱怨了(gcc也会抱怨).
As you cannot take the sizeof
of a function, clang rightly complains (and gcc would too).
作为一种解决方法,传入一个函数指针:
As a workaround, pass in a function pointer:
for_each(&func, nullptr);
我填写了一个错误报告,该问题已修复! :)
I filled a bug report, which was fixed! :)
这篇关于noexcept说明符神秘地破坏了编译(clang,gcc表示不同意)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!