代码:
#include<iostream>
using namespace std;
void foo() throw(char) {throw 'a';}
int main() try {
void (*pf)() throw(float);
pf = foo; // This should NOT work
pf();
}
catch(const char& c){cout << "Catched ::> " << c << endl;}
为什么即使foo
异常规范与函数指针pf
不同,也可以将foo
传递给pf
?这是我的编译器中的错误吗?
答案 0 :(得分:9)
<强> Exception specifications don’t participate in a function’s type. 强> 更正: 正如其他答案所指出的那样,它确实是一个编译器错误。众所周知,大多数编译器在实现异常规范时都存在问题。此外,它们在C ++ 11中已弃用。所以,
遵循Herb Sutter对异常规范的建议:
道德#1:永远不要编写异常规范。
道德#2:除了可能是一个空洞的,但如果我是你,我甚至会避免。
答案 1 :(得分:5)
是的,这是编译器错误。函数指针必须具有可分配的兼容异常说明符。
引自标准:
15.4例外规范
(5)......类似的限制适用于对指针的赋值和初始化 函数,指向成员函数的指针以及对函数的引用:目标实体 至少应允许赋值或初始化中源值允许的例外。
示例:强>
class A;
void (*pf1)(); // no exception specification
void (*pf2)() throw(A);
pf1 = pf2; // OK: pf1 is less restrictive
pf2 = pf1; // error: pf2 is more restrictive
使用Comeau编译的代码会导致incompatible exception specifications
错误:
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions
"ComeauTest.c", line 9: error: incompatible exception specifications
pf=foo; // This should NOT work
^
正如许多其他人所提到的,除了noexcept
规范之外,C ++ 11标准中不推荐使用异常规范(见附录D.4)。所以最好的做法是(并且是) - 避免使用。