C++ C++;17异常说明符类型系统工作?
在研究“noexcept说明符(和运算符)”时,我编写了一个简单的代码。我很惊讶这段代码:C++ C++;17异常说明符类型系统工作?,c++,c++11,c++14,c++17,noexcept,C++,C++11,C++14,C++17,Noexcept,在研究“noexcept说明符(和运算符)”时,我编写了一个简单的代码。我很惊讶这段代码: void asdf()noexcept{} int main() { 自动f=asdf; 标准::cout 根据这个(已接受的)建议,由于C++17;由于noexcept是函数类型的一部分,上面的代码是否会打印true 是。 f的类型将被推断为void(*)()noexcept,因为应用于asdf的函数到指针转换将保留noexcept属性。调用noexcept函数指针肯定不会引发异常,除非其子表达式之一发
void asdf()noexcept{}
int main()
{
自动f=asdf;
标准::cout
根据这个(已接受的)建议,由于C++17;由于noexcept是函数类型的一部分,上面的代码是否会打印true
是。
f
的类型将被推断为void(*)()noexcept
,因为应用于asdf
的函数到指针转换将保留noexcept
属性。调用noexcept
函数指针肯定不会引发异常,除非其子表达式之一发生异常
关于确切的措辞,请参见和。注意,C++17草案后一段中的新措辞来自P0012R1,它在OP中链接
如果表达式([except.spec])的潜在异常集为空,则noexcept
运算符的结果为true
,否则为false
- 如果
e
是函数调用([expr.call]):
- 如果其后缀表达式是一个id表达式([expr.prim.id])、类成员访问([expr.ref])或成员操作指针([expr.mptr.oper]),其强制转换表达式是一个id表达式,则S是由包含的id表达式选择的实体的异常规范中的类型集(过载解决后,如适用)。
因此f()
的潜在异常集与f
的异常规范中的类型集相同,这是空的,因为f
被声明为noexcept
让我们转到第二个问题:
在C++14或C++11中,noexcept
指定似乎被忽略。此代码在C++17中是否能正常工作
您的问题似乎是:std::function
是否会拒绝保留可能引发异常的函数
我想说它是不清楚的。在标准的当前措辞中,std::function
实际上没有定义,正如。这在C++14中当然不是问题,因为noexcept
不被视为函数类型的一部分
<> >代码> STD::函数< /C>简单地在C++ 17中破译吗?这对我来说是不确定的。让我们看看当前的措辞来猜测应该是什么行为。
该标准要求std::function
的构造函数的参数对于参数类型ArgTypes…
和返回类型R
是“可调用的左值”,其中:
可调用类型([func.def])F
对于参数类型ArgTypes
和返回类型R
,如果被视为未赋值操作数(子句[expr])的表达式INVOKE(declval(),declval()…,R)
格式良好([func.require])
也许应该有一个额外的要求,即如果函数类型是noexcept
,那么noexcept(INVOKE(…)
也必须是true。尽管如此,当前草案中没有这一措辞
在P0012R1中,有一条注释:
如何通过std::function
传播“noexcept”是一个悬而未决的问题
我的猜测是,他们的意思是,如果强加了这个额外的要求,还不清楚如何实现std::function
。希望其他人能提供更多的细节。g++返回true
对于noexcept(f())
没有-std=c++1z
(但clang确实返回false
)。为了获得更多乐趣,请将auto f=asdf;
更改为void(*f)()noexcept=asdf;
。现在GCC打印false
,而clang打印true
@Holt感谢您提供的信息。我正在使用MSVC(返回false
)。它们有什么不同?是g++或C++14或早期标准的bug没有指定任何关于noexcept
类型系统的内容吗?@hvd对于该代码,MSVC打印true
。我现在很困惑:p@hvd对于函数指针版本,如果您删除asdf
上的noexcept
,则clang将拒绝做作but gcc没有抱怨……我猜gcc忽略函数指针声明上的noexcept
。显然,我们需要std::function\u moveonly
和std::function\u noexceptonly
和std::function\u moveonly\u noexceptonly
。但是std::function\u mutablecall
呢?这可能会很混乱。