Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using noexcept as a lambda modifier or parameter constraint

Tags:

Can the noexcept modifier be applied to a lambda expression? If so, how?

Can noexcept be made a constraint on a function argument? For example, something like in the following code, where the meaning is that the callback function must be noexcept?

//probably not valid code - I'm just trying to express the idea void f_async(std::function<void (int) noexcept> callback) noexcept {     ... } 

This can almost be accomplished with the following code, but I'm wondering if there is a way to use something like the above alternative.

void f_async(std::function<void (int)> callback)     noexcept(callback(std::declval<int>())) {     ... } 

The problem here of course is that f_async can be noexcept(false) if the callback is noexcept(false) - I want to make a stronger statement that f_async is always noexcept, meaning it's only callable if you use a noexcept callback.

like image 445
Timothy Shields Avatar asked May 15 '13 17:05

Timothy Shields


People also ask

When should you use Noexcept?

E. 12: Use noexcept when exiting a function because of a throw is impossible or unacceptable. you don't care in case of an exception. You are willing to crash the program because you can not handle an exception such as std::bad_alloc due to memory exhaustion.

What does Noexcept mean in C ++?

The noexcept operator performs a compile-time check that returns true if an expression is declared to not throw any exceptions. It can be used within a function template's noexcept specifier to declare that the function will throw exceptions for some types but not others.

How do you pass a lambda function in C++?

Permalink. All the alternatives to passing a lambda by value actually capture a lambda's address, be it by const l-value reference, by non-const l-value reference, by universal reference, or by pointer.

Can lambdas be Inlined?

Inlinable lambdas can only be called inside inline functions or passed as inlinable arguments. noinline lambdas, however, can be manipulated in any way you like, including being stored in fields or passed around.


1 Answers

Can the noexcept modifier be applied to a lambda expression? If so, how?

Add noexcept after the parenthesis:

[](Args args) noexcept { ... } 

Can noexcept be made a constraint on a function argument?

Yes, use enable_if:

template <typename F> auto f_async(const F& func) noexcept          -> typename std::enable_if<noexcept(func(0))>::type {     func(0); }  int main() {     f_async([](int x) noexcept {});     f_async([](int x) {}); // <- this line won't compile } 

However, this method cannot work directly in g++ 4.7 (it does work in clang++ 3.2), because it cannot mangle noexcept expression yet:

3.cpp:5:6: sorry, unimplemented: mangling noexcept_expr

You could workaround it using a wrapper struct:

template <typename F, typename... Args> struct EnableIfNoexcept          : std::enable_if<noexcept(std::declval<F>()(std::declval<Args>()...))> {};  template <typename F> auto f_async(const F& func) noexcept -> typename EnableIfNoexcept<F, int>::type {     func(0); } 
like image 68
kennytm Avatar answered Oct 09 '22 11:10

kennytm