用于检测函数类型是否为否的特征

Trait to detect if a function type is maked noexcept

本文关键字:特征 是否 检测 函数 类型 用于      更新时间:2023-10-16

我想知道是否有技巧可以简化特征的编写以返回类型是否为noexcept函数。目前我的实现如下,它只是一一列出了所有可能性。可以使用标准C++20以更简单的方式编写吗?

// Default
template <class>
struct is_noexcept_function: std::false_type {};
// Variable template
template <class T>
inline constexpr bool is_noexcept_function_v
= is_noexcept_function<T>::value;
// Noexcept functions
template <class R, class... Args>
struct is_noexcept_function<R(Args...) noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args...) const noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args...) volatile noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args...) const volatile noexcept>: std::true_type {};
// Noexcept lvalue-ref-qualified functions
template <class R, class... Args>
struct is_noexcept_function<R(Args...) & noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args...) const & noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args...) volatile & noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args...) const volatile & noexcept>: std::true_type {};
// Noexcept rvalue-ref-qualified functions
template <class R, class... Args>
struct is_noexcept_function<R(Args...) && noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args...) const && noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args...) volatile && noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args...) const volatile && noexcept>: std::true_type {};
// Noexcept variadic functions
template <class R, class... Args>
struct is_noexcept_function<R(Args..., ...) noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args..., ...) const noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args..., ...) volatile noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args..., ...) const volatile noexcept>: std::true_type {};
// Noexcept lvalue-ref-qualified variadic functions
template <class R, class... Args>
struct is_noexcept_function<R(Args..., ...) & noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args..., ...) const & noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args..., ...) volatile & noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args..., ...) const volatile & noexcept>: std::true_type {};
// Noexcept rvalue-ref-qualified variadic functions
template <class R, class... Args>
struct is_noexcept_function<R(Args..., ...) && noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args..., ...) const && noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args..., ...) volatile && noexcept>: std::true_type {};
template <class R, class... Args>
struct is_noexcept_function<R(Args..., ...) const volatile && noexcept>: std::true_type {};

您的问题有两个部分:检测类型是否为函数,然后检测该函数是否为 noexcept。遗憾的是,没有更好的方法来检测类型是否为函数。即使在 20 C++也没有。您确实需要专注于恒量、易失性和参考资格的所有组合。

当 noexcept 在 C++17 中成为函数类型的一部分时,这一事实至少给一个标准库实现者带来了很大的挫败感。

在此处查看我自己的(免费(解决方案(生产级,完整文档(。这是对本文中讨论的想法的完整实现。

下载代码,将"TypeTraits.h"和"CompilerVersions.h"添加到项目中,然后执行以下操作(注意存在传递函数类型的其他方法 - 请参阅文档(。请注意,您不必显式 #include"CompilerVersions.h",它会自动 #included 在"TypeTraits.h"中。

#include "TypeTraits.h"
using namespace StdExt; // Everything's in this namespace
constexpr bool isNoexcept = IsNoexcept_v<decltype(YourFunction)>;