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

C++ 如何检测模板参数是否为noexcept函数?,c++,templates,c++11,c++14,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&

我有一个函数来生成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 )... );
    };
}
我的尝试:

#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
}
#包括
void f(){}
void g()noexcept{}
模板
结构是_noexcept:std::false_type{};
模板
结构是_noexcept:std::true_type{};
int main()
{
bool constexpr func_test_a{is_noexcept::value};//true
bool constexpr func_test_b{is_noexcept::value};//true
}
但是,测试总是返回
true
。我错过了什么?有人能提供此问题的解决方案吗?

您可以使用,它接受一个表达式并生成
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 )... );
};
return[&]()noexcept(noexcept(std::forward(f)(std::forward(f_参数)…))
->std::测试结果
{
返回std::forward(f)(std::forward(f_参数)…);
};
来自:

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


目前,模板推断不会产生正确的结果,因为
noexcept
说明符不是函数类型的一部分;模板类型推断在C++17之前不起作用。我检测函数是否为
noexcept
的方法在C++17中和will的方法一样有效。

这是我尝试的第一件事,但对于
f()
g()
,它仍然返回
true
。正如我在回答中指出的,这将是C++17中的有效答案。gcc 7.3.1和clang 5.0.2进行了大量测试
noexcept
给定编译时实例类型的任何变化(
std::declval
std::forward
,简称
f
),而不是C++11或C++14中的表达式,总是导致
false
。gcc甚至对此发出警告。再一次,它经受了严峻的考验。奇怪的是,我的
/usr/include/c++/type\u traits
中的
std::is\u nothrow\u destructible
实现依赖于类似
std::integral\u constant
的东西,但我认为这是一个灰色区域表达式(尽管仍然令人困惑)。
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 )... );
};