如何检测模板参数是否为noexcept函数

How can I detect whether a template argument is a noexcept function?

本文关键字:是否 参数 noexcept 函数 何检测 检测      更新时间:2023-10-16

我有一个函数来生成一个lambda,它充当我稍后可以调用的函数的包装器:

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 )... );
    };
}

当参数fnoexcept时,我想使返回的lambda noexcept,所以我的函数的返回如下所示:

return [&] () noexcept( is_noexcept<decltype( f )>::value )
    -> std::result_of_t<F( FArgs... )>
{
    return std::forward<F>( f )( std::forward<FArgs>( f_args )... );
};

我的尝试:

#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
}

但是,测试总是返回true。我错过了什么?有人能为这个问题提供解决方案吗?

来源:http://en.cppreference.com/w/cpp/language/noexcept_spec

noexcept规范不是函数类型的一部分。(直到C++17)。

目前,模板推导不会产生正确的结果,因为noexcept说明符不是函数类型的一部分;模板类型推导要到C++17才能工作。我检测函数是否为noexcept的方法在C++17中是有效的,这个答案的方法也是有效的。

您可以使用noexcept运算符,该运算符接受一个表达式并在该表达式为noexcept时生成true

未测试,但这可能适用于您的用例。

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 )... );
};
相关文章: