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

时间:2015-11-08 01:29:11

标签: c++ templates c++11 c++14

我有生成lambda的函数,该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 )... );
    };
}

我希望在参数noexceptf时返回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。我错过了什么?任何人都可以提供这个问题的解决方案吗?

2 个答案:

答案 0 :(得分:12)

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

  

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

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

答案 1 :(得分:6)

您可以使用noexcept operator,如果该表达式为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 )... );
};