Reputation: 2837
I have function to generate a lambda that acts as a wrapper to a function I can invoke later:
template <typename F, typename... FArgs>
auto make_lambda( F&& f, FArgs&&... f_args )
{
return [&] () -> std::result_of_t<F( FArgs... )>
{
return std::forward<F>( f )( std::forward<FArgs>( f_args )... );
};
}
I'd like to make the returned lambda noexcept
when argument f
is noexcept
, so my function's return would look like this:
return [&] () noexcept( is_noexcept<decltype( f )>::value )
-> std::result_of_t<F( FArgs... )>
{
return std::forward<F>( f )( std::forward<FArgs>( f_args )... );
};
My attempt:
#include <type_traits>
void f() {}
void g() noexcept {}
template <typename F, typename... Args>
struct is_noexcept : std::false_type {};
template <typename F, typename... Args>
struct is_noexcept<F( Args... ) noexcept> : std::true_type {};
int main()
{
bool constexpr func_test_a{ is_noexcept<decltype( f )>::value }; // true
bool constexpr func_test_b{ is_noexcept<decltype( g )>::value }; // true
}
However, the test always returns true
. What am I missing? Can anyone provide a solution to this problem?
Upvotes: 10
Views: 4257
Reputation: 2837
From: http://en.cppreference.com/w/cpp/language/noexcept_spec
The noexcept-specification is not a part of the function type. (until C++17).
Currently, template deduction will not produce the correct results since the noexcept
specifier is not part of a function's type; template type deduction will not work until C++17. My way of detecting whether a function is noexcept
will be valid in C++17 as will this answer's way.
Upvotes: 13
Reputation: 16355
You can use the noexcept
operator, which takes an expression and produces true
if that expression is noexcept
.
Untested, but this might work for your use case.
return [&] () noexcept(noexcept(std::forward<F>( f )( std::forward<FArgs>( f_args )... )))
-> std::result_of_t<F( FArgs... )>
{
return std::forward<F>( f )( std::forward<FArgs>( f_args )... );
};
Upvotes: 12