clang如何检测noexcept-ness?

时间:2017-08-24 22:41:19

标签: c++ templates c++14 metaprogramming

我目前正在C ++ 11中重新实现std::invoke(即理解和调整libc ++ / libstdc ++代码),我偶然发现了与noexcept相关的问题。

这可以通过以下代码段来演示:

#include <functional>

void nothrow_method(int, int) noexcept
{
}

int main(int argc, char const *argv[])
{
  static_assert(noexcept(std::__invoke(nothrow_method, 2, 3)), "");
  static_assert(std::__is_nothrow_invocable<decltype(nothrow_method), int, int>::value, "");
}

我在Debian Jessie,我的库是libstdc ++。

-std=c++14进行编译失败,并使用clang 4.0.1,static_assert触发。 但是GCC 7.1.0没有问题。

我看了libc ++如何实现std::invoke,我在自己的实现中复制了检测noexcept的方式,但它仍然无法编译。

由于static_assert只有一个错误行,我真的不知道发生了什么,是否与此blog post中解释的内容有关?

我过去曾遇到noexcept和模板实例化点的问题,但我很确定它与此无关。

修改

我已经下载了libcxx trunk,在macOS 10.12.6上使用apple-clang 8.1.0构建,static_assert仍然触发,尽管它们的代码在noexcept(noexcept())上有__invoke。< / p>

EDIT2:

std::__*用于测试,我知道它们是私有的,但我不想发布我的invoke实现。

1 个答案:

答案 0 :(得分:0)

这似乎是Clang标准库的一个错误,可能在std :: invoke&lt;&gt;的定义中和std :: __ is_nothrow_invocable&lt;&gt; ... GCC在两个语句中都没有正确断言,VS2017确实出现了这个错误。

顺便说一句,你应该避免使用std :: __ *&lt;&gt;模板 - 它们不是标准的一部分,并且是私有的标准库。

这是一种解决方法:您可以使用以下语法,这更正确,因为它会测试您将在应用中使用的实际语句。

#include <functional>

void nothrow_method(int, int) noexcept { }

int main()
{
    static_assert(noexcept(nothrow_method(2, 3)), "");
    return 0;
}