## Question:

Motivation: In the implementation of P0288`std::move_only_function`

, I’d like to write a non-allocating special case for conversion from `move_only_function<int() noexcept>`

to `move_only_function<int()>`

:```
move_only_function<int() noexcept> f = []() noexcept { return 42; };
move_only_function<int()> g = std::move(f); // should just copy the bits
```

I want to write, like,```
if constexpr (is_noexcept_version_of<HisSignature, MySignature>::value) { ... }
```

I wanted to implement that type trait like this:```
template<class, class>
struct is_noexcept_version_of : std::false_type {};
template<class Tp>
struct is_noexcept_version_of<Tp noexcept, Tp> : std::true_type {};
```

but no vendor accepts that; they all think `Tp noexcept`

is a syntax error.Question: How would you write this kind of type-trait without a combinatorial explosion of partial specializations, i.e. without exhaustively going through all the possible combinations of

`&`

, `&&`

, `const`

, etc.? Is it possible to write simple closed-form type traits for `is_noexcept_v<T>`

, `add_noexcept_t<T>`

and `remove_noexcept_t<T>`

?## Answer:

Aside from qualification conversions, the only possible implicit conversions between pointer-to-function types are the ones that remove`noexcept`

and similarly for pointers-to-member-functions (except for base-to-derived conversion), so I think the following should work```
struct C {};
template<class A, class B>
struct is_noexcept_version_of : std::bool_constant<
requires {
requires std::is_convertible_v<A C::*, B C::*>;
requires std::is_function_v<A>;
requires !std::is_same_v<A, B>;
}> {};
```

If you have better answer, please add a comment about this, thank you!

If you like this answer, you can give me a coffee by <a href=”https://violencegloss.com/mkw7pgdwwr?key=2a96ade6f3760c7e63343a320febb78e”>click here</a>

Source: Stackoverflow.com

## Leave a Review