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?
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.
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 )... );
};
来源:https://stackoverflow.com/questions/33589752/how-can-i-detect-whether-a-template-argument-is-a-noexcept-function