c++ - noexcept 说明符神秘地破坏了编译(clang,gcc 不同意)

标签 c++ c++11 gcc clang noexcept

有问题的代码是

#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.");
                  ^~~~~~~~~~~
/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 */ {}

然后编译。我不明白这个。这是编译器错误吗?

最佳答案

嗯,不。 libc++ 无法处理 noexcept 标记的函数。当函数是 noexcept 并且它采用错误的部分特化(用于对象而不是函数的部分特化)时,它的机制似乎由于某种原因失败了。

由于您无法获取函数的 sizeof,因此 clang 正确地提示(gcc 也会如此)。

作为一种解决方法,传入一个函数指针:

for_each(&func, nullptr);

我填写了 bug report ,这是固定的! :)

关于c++ - noexcept 说明符神秘地破坏了编译(clang,gcc 不同意),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50273399/

相关文章:

c - 在 ubuntu 中使用 gcc 生成特定频率的声音?

c - 为什么我没有 "undefined reference to"?

c++ - 在大型项目中以现代 CMake 方式添加 header

c++ - 调试器在 Eclipse 中找不到源文件

c++ - 功能是必需的

c - 冗余 __packed__ 属性

c++ - 在无向图上设置值

c++ - 如何迭代所有 malloc block (glibc)

c++ - 如何在回溯中显示 lambda 函数?

保留换行符的 C++ 预处理器字符串化?