用于检测函数类型是否标记为 noexcept 的特性

7

我在想是否有什么诀窍可以简化编写一个trait以返回一个类型是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 {};

1
这不就是std::is_nothrow_invocable吗? - NathanOliver
1
@NathanOliver 除了这个,我认为要正确调用它,你需要专门处理所有可能的函数变体,这会让你回到完全相同的问题。如果你能够做到这一点,因为我没有想到什么,我很想看看你的答案。 - Vincent
1
这个类似的问题:https://dev59.com/3F4c5IYBdhLWcg3wl7Tm 看起来你必须编写所有这些特殊化。 - Artyer
2个回答

1

你的问题有两个部分:检测类型是否为函数,然后检测该函数是否为noexcept。不幸的是,没有更好的方法来检测类型是否为函数,即使在C++20中也是如此。你确实需要为所有const、volatile和ref资格的组合进行专门化。

这个事实至少让一个标准库实现者在C++17中,当noexcept成为函数类型的一部分时感到非常沮丧。


0

请查看我自己的(免费)解决方案这里(生产级别,完全记录)。这是本文讨论的思路的完整实现。

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接