【发布时间】:2021-11-19 20:26:20
【问题描述】:
例如我有输入:
typedef DWORD WINAPI HANDLER_FUNCTION_EX (DWORD);
我想要:
static as_noexcept<HANDLER_FUNCTION_EX>::type my_func; // forward declaration
static_assert(noexcept(my_func(0)));
我得到了类似的东西:
template<typename>
struct noexcept_trait;
// specialization to infer signature
template<typename Result, typename... Args>
struct noexcept_trait<Result(Args...)>
{
using as_noexcept = Result(Args...) noexcept;
using as_throwing = Result(Args...);
};
// since C++17 noexcept-specification is a part of the function type
// so first specialization won't match
template<typename Result, typename... Args>
struct noexcept_trait<Result(Args...) noexcept>
{
using as_noexcept = Result(Args...) noexcept;
using as_throwing = Result(Args...);
};
template<typename T>
using add_noexcept_t = typename noexcept_trait<T>::as_noexcept;
template<typename T>
using remove_noexcept_t = typename noexcept_trait<T>::as_throwing;
但是这段代码创建了全新的类型并删除了所有附加信息(调用约定、属性,例如[[deprecated]])。所以不安全。我该如何解决?
【问题讨论】:
-
你确定
HANDLER_FUNCTION_EX()不是在扔吗?即使它是纯 C 函数,如果它可能间接调用另一个函数,则该函数可能会抛出异常。请参阅this question 以获得有趣的阅读。 -
@G.Sliepen
HANDLER_FUNCTION_EX只是函数类型名称。实际函数是my_func,用noexcept定义,所以肯定不会抛出。 -
如果您的编译器扩展了类型系统以具有调用约定修饰符,您就不能添加更多的特化来处理这些情况吗?可以肯定的是,这很长,但并不难。
-
@DavisHerring
__attribute__((stdcall))或__stdcall不是函数类型的一部分,因此所有特化都存在冲突(错误:已定义类模板) -
@DavisHerring 它失败了,因为在 x64 模式下,msvc 将 __cdecl 视为 __stdcall。如果我选择 x86 目标,它们将被视为不同的类型。 devblogs.microsoft.com/oldnewthing/20200717-00/?p=103989
标签: c++ visual-c++ c++20