[英]using vs typedef pointer-to-noexcept-function inconsistency
我意识到我可以通过using
声明一个指向noexcept
函数的指针的类型,但是如果我使用typedef
则禁止这样的声明。 请考虑以下代码:
#include <iostream>
using fptr = void(*)() noexcept;
// typedef void(*FPTR)() noexcept; // fails to compile
void f() noexcept
{
std::cout << "void f() noexcept" << std::endl;
}
void g()
{
std::cout << "void g()" << std::endl;
throw 10;
}
int main()
{
fptr f1 = f;
fptr f2 = g; // why can we do this?
try {
f1();
f2();
}
catch (...)
{
std::cout << "Exception caught" << std::endl;
}
}
如果我取消注释FPTR
声明,我就会得到
error: 'FPTR' declared with an exception specification
但是, using
效果很好。 用gcc4.9和gcc5编译。
我的问题是:
using
noexcept
using
,因为我们可以将指针绑定到未声明为noexcept
函数,如行fptr f2 = g;
似乎是一个与gcc相关的bug,即使gcc5也没有抓住它。 填写错误报告
这似乎是海湾合作委员会的一个错误; Clang拒绝两者,因为类型别名或typedef
不允许使用异常规范。 这可以在以下位置找到:
15.4例外规范[except.spec]
2 异常规范只应出现在函数类型的函数声明符,函数类型的指针,函数类型的引用或成员函数类型的指针上,该成员函数类型是声明或定义的顶级类型,或者是这样的类型在函数声明符中显示为参数或返回类型。 异常规范不应出现在typedef声明或alias-declaration中 。
[...]
该标准还明确指出两者应该是一致的:
7.1.3
typedef
说明符[dcl.typedef]2 别名声明也可以引入typedef-name 。
using
关键字后面的标识符变为typedef-name,并且该标识符后面的可选attribute-specifier-seq属于该typedef-name 。 它具有与typedef
说明符引入的语义相同的语义 。 特别是,它没有定义新类型,它不应出现在type-id中 。
(强调我的)
回答你的第二个问题:GCC可能只是忽略了异常规范,因为函数不能仅仅在异常规范上重载 - 它不是函数签名的一部分。 这可以在这里找到:
8.3.5函数[dcl.fct]
6 [...]返回类型,参数类型列表, ref-qualifier和cv-qualifier-seq ,但不是默认参数(8.3.6)或异常规范(15.4),是功能类型。 [ 注意:在指向函数的指针和函数的引用以及指向成员函数的指针的赋值和初始化期间,将检查函数类型。 - 结束说明 ]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.