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

use*_*177 10 c++ templates c++11 c++14

我有生成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 )... );
    };
}
Run Code Online (Sandbox Code Playgroud)

我想noexcept在参数f为的时候返回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 )... );
};
Run Code Online (Sandbox Code Playgroud)

我的尝试:

#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
}
Run Code Online (Sandbox Code Playgroud)

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

use*_*177 12

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

noexcept-specification不是函数类型的一部分.(直到C++ 17).

目前,模板推导不会产生正确的结果,因为说明noexcept符不是函数类型的一部分; 模板类型推导在C++ 17之前不起作用.检测函数是否noexcept有效的方法在C++ 17中是有效的,这个答案也是如此.


Jer*_*man 6

您可以使用noexcept运算符,它接受表达式并生成true表达式noexcept.

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

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 )... );
};
Run Code Online (Sandbox Code Playgroud)