我目前正在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
实现。
答案 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;
}