如何为 noexcept 函数指针创建别名
How do I create an alias for a noexcept function pointer?
我想这样做:
using function_type = void (*)(void*)noexcept;
但是我收到一个错误"类型别名中不允许异常规范"。(在 Xcode 6.1 版本中的 clang (
是否有解决方法可以创建带有 noexcept 说明符的别名?
我正在寻找由跨平台功能的语言(而不是扩展(定义的东西。
该标准明确禁止异常规范出现在typedef
或别名声明中。但它也指出异常说明符可能出现在函数指针类型中。
§15.4/2 [规格除外]
如果指向函数的指针异常规范应仅出现在函数类型的函数声明符、指向函数类型的指针、对函数类型的引用或指向作为声明或定义的顶级类型的成员函数类型的指针上,或者出现在函数声明符中显示为参数或返回类型的此类类型上。例外规范不得出现在
typedef
声明或别名声明中。
确实具有异常规范,则必须始终为该函数指针分配具有兼容异常规范的函数类型。
§15.4/5
...
类似的限制适用于指向的指针的赋值和初始化 函数、指向成员函数的指针和对函数的引用:目标实体应至少允许赋值或初始化中源值允许的异常。...
使用这两个,您可以以迂回的方式将noexcept
规范转换为函数指针类型。
void (*foo_ptr)(void *) noexcept = nullptr;
using function_type = decltype(foo_ptr);
现在,您无法将没有 noexcept(true)
规范的函数分配给类型 function_type
的函数指针。 clang 将无法编译代码并显示错误
错误:目标异常规范不是源的超集
Praetorian 答案的替代方案,它不涉及声明变量:
void unused_function(void*)noexcept;
using function_type = decltype(&unused_function);
已声明unused_function
,但未定义。
作为这个答案的推论,你寻求的模式很简单:
using function_type = decltype(std::declval<function_type_declaration>());
即
#include <utility>
//...
using function_type = decltype(std::declval<void (*)(void*)noexcept>());
这不适用于extern
链接,包括extern "C"
,即:
// INVALID
using function_type = decltype(std::declval<extern "C" void(*)(void)>());
// WORKAROUND
extern "C" void function_type_dummy(void);
using function_type = decltype(&function_type_dummy);
为了进一步简化这个答案,我们可以按如下方式使用类型特征std::add_pointer
:
using function_type = std::add_pointer_t<void(void*) noexcept>;
来自 cpp首选项文档(强调我的(:
如果 T 是引用类型,则提供成员 typedef 类型,该类型是指向引用类型的指针。
否则,如果 T 命名对象类型,则不是 cv 或 ref 限定的函数类型,或(可能符合 cv 限定的(void 类型,则提供成员类型定义类型,即类型 T*。
否则(如果 T 是 cv 或 ref 限定的函数类型(,则提供成员 typedef 类型,该类型为 T。
换句话说,std::add_pointer
的实现方式使其与类似函数签名的表达式兼容,如C++模板参数。
extern "C"
函数的限制仍然适用,因此您需要使用我链接的答案中的解决方法。
- 使用基类指针创建对象时,缺少派生类析构函数
- 如何在没有数据拷贝的情况下从指针创建一个Eigen VectorXd对象
- 如何从绝对地址的 C 样式指针创建对C++对象的引用
- 不明白使用双指针 (**) 创建 2d 动态数组
- 如何使用指向动态数组的静态指针创建类?
- Opencl:从 c 样式指针创建 UserEvent
- 从 uint16 指针创建垫子
- 如何为指针创建类型定义
- 从原始指针创建const_iterator会在 macOS 上产生编译错误
- 为什么可以使用指针创建新结构,但不能以相同的方式创建双精度?
- 是否可以在 c++17 中为 c 样式指针或原始指针创建弱指针
- 调用虚拟函数而不通过类类型指针创建任何对象
- 如何使用双指针创建指针数组?
- 使用指针创建类成员
- 如何使用成员函数指针创建模板类
- 从现有指针C 创建一个新对象
- 使用指针创建动态数组的问题
- 如何为指向数组的指针创建内存集?
- 使用共享指针创建的链表数组
- 使用C++ 11 中的模板类型的成员函数指针创建方法参数