C++ 如何检测模板参数是否为noexcept函数?
我有一个函数来生成lambda,它充当我以后可以调用的函数的包装器: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&
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 )... );
};