I have a functor to perform static casts from any type to a specific type, defined in this way:
template <typename T_Out>
struct cast_to {
template <typename T_In>
T_Out operator()(T_In&& value) const noexcept {
return static_cast<T_Out>(value);
}
};
Now, I would like to restrict the use of the functor to those static casts expressions that are declared, implicitly or explicitly, as noexcept
. The idea is to add some static assertion in the operator()
function. So far, I've tried with two constexpr expressions:
std::is_nothrow_constructible<T_Out, decltype(value)>::value
and
noexcept(static_cast<T_Out>(value))
Both seems to work as I expect (actually, I've seen that the first check includes also the other, at least on GCC). Which approach should I prefer? Are there better alternatives?
It depends on how technically correct you want to go. As you have said, both options achieve the intended goal - prevent compilation. The difference is:
std::is_nothrow_constructible test will always evaluate to either true or false, making your assertion pass or fail.
noexcept test will either evaluate to true, to false, or will fail to compile inner static_cast check if you pass arguments that don't convert at all.
I would go with one of the following:
Option 2 might have better diagnostics, but option 1 may be more technically correct. It's personal preferences.