使用绑定的noexcept保存

发布于 2025-01-17 20:03:53 字数 893 浏览 3 评论 0原文

我在 < 中保存 noexcept 说明符时遇到问题代码>std::bind,使用C++17。 在 GCC 和 Clang 中没有保留,但在 MSVC 中是。似乎将 bind 与带有 noexcept 说明符的函数一起使用,生成的对象不会保留它,始终考虑到它不是 noexcept

具有如下功能:

void f(int) noexcept;

现在创建一个带有 std::bind 的可调用对象:

auto g = std::bind(f,5);

可以看出 noexcept 行为在 f 之间是不同的在 GCC 和 Clang 中执行时(使用 C++17 模式)和 g

std::cout << noexcept(f(5)); //prints 1, ok, as expected
std::cout << noexcept(g()); //prints 0, WRONG!!

正如开头提到的,MSVC 是唯一具有(在我看来)一致行为的。阅读标准规范没有提到任何相关内容,所以也许没有指定这种行为 那么,这是由于标准中缺乏规范而导致的正常行为还是一个错误?

使用 bind 时有什么方法可以强制使用“noexcept”说明符?

I have a problem with preservation of noexcept specifier in std::bind, using C++17.
In GCC and Clang is not preserved, but in MSVC it is. It seems that using bind with a function with noexcept specifier, the resulting object doesn't preserve it, considering always that it isn't noexcept.

Having a function like:

void f(int) noexcept;

And now creating a callable with std::bind on it:

auto g = std::bind(f,5);

It can be seen that noexcept behaviour is different between f and g when executing in GCC and Clang (using C++17 mode)

std::cout << noexcept(f(5)); //prints 1, ok, as expected
std::cout << noexcept(g()); //prints 0, WRONG!!

As mentioned at the beginning, MSVC is the only with (in my opinion) consistent behaviour. Reading the standard specification doesn't mention anything about that, so maybe this behaviour is not specified
So, is this a normal behaviour because the lack of specification in the standard or is a bug?

Is any way to force the "noexcept" specifier when using bind?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

天冷不及心凉 2025-01-24 20:03:53

如果您可以使用 C++20,那么您可以使用 std ::bind_front,不仅性能比std::bind更好,而且完美转发的operator()称呼如果它调用的 std::invoke 表达式是 noexcept,它返回的包装器是 noexcept (换句话说,它保留异常底层调用运算符的规范),因此以下 static_assert 可以传递给所有三个编译器

#include <functional>

void f(int) noexcept;

auto g = std::bind_front(f,5);

static_assert(noexcept(f(5)));
static_assert(noexcept(g()));

演示

If you can use C++20, then you can just use std::bind_front, which not only has better performance than std::bind, but the operator() of the perfect forwarding call wrapper it returns is noexcept if the std::invoke expression it calls is noexcept (in other words, it preserves the exception specification of the underlying call operator), so the following static_assert can pass for all three compilers

#include <functional>

void f(int) noexcept;

auto g = std::bind_front(f,5);

static_assert(noexcept(f(5)));
static_assert(noexcept(g()));

Demo

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文