该noexcept关键字可以适当地应用于许多功能签名,但我不能确定何时我应该考虑在实践中使用它.根据我到目前为止所读到的内容,最后一分钟的添加noexcept似乎解决了移动构造函数抛出时出现的一些重要问题.但是,我仍然无法对一些实际问题提供令人满意的答案,这些问题使我首先要了解更多信息noexcept.
我知道永远不会抛出许多函数的例子,但编译器无法自行确定.noexcept在所有这些情况下我应该附加到函数声明吗?
不得不考虑我是否需要noexcept在每个函数声明之后追加,这将大大降低程序员的工作效率(坦率地说,这将是一个痛苦的屁股).对于哪些情况,我应该更加小心使用noexcept,以及在哪些情况下我可以使用暗示noexcept(false)?
我何时才能真实地期望在使用后观察到性能提升noexcept?特别是,给出一个代码示例,C++编译器在添加之后能够生成更好的机器代码noexcept.
就个人而言,我关心的是noexcept因为编译器提供了更大的自由来安全地应用某些类型的优化.现代编译器是否noexcept以这种方式利用?如果没有,我可以期待他们中的一些人在不久的将来这样做吗?
对于许多问题,答案似乎可以在"标准"中找到.但是,我们在哪里找到它?最好是在线.
谷歌搜索有时会觉得徒劳,尤其是对于C标准,因为他们在编程论坛的大量讨论中被淹没.
要开始这个,因为这些是我现在正在搜索的,那里有很好的在线资源:
throw在函数签名中使用C++ 关键字被认为是不良做法的技术原因是什么?
bool some_func() throw(myExc)
{
...
if (problem_occurred)
{
throw myExc("problem occurred");
}
...
}
Run Code Online (Sandbox Code Playgroud) 有没有之间的任何其他差别throw()和noexcept除了被检查的运行时分别编译时间?
维基百科C++ 11文章表明不推荐使用C++ 03 throw说明符.
为什么这样,noexcept有足够的能力在编译时覆盖所有这些?
我在使用C++代码时遇到了问题,这些代码意外地对调用者抛出异常.读取用于查看是否抛出异常的模块的每一行并不总是可行或实际的,如果是,则抛出异常类型.
是否存在处理此问题的成语或"最佳实践"?
我想到了以下几点:
在我们的doxygen文档中,我们可以在每个预期会抛出异常及其类型的函数中添加注释.
我们可以安装应用程序try/catch(...).
使用例外规范
有这些方法的经验,还是我不知道的任何其他方法?
我有两个关于非投掷功能的问题:
为什么要使一个函数不抛?
如何使功能不抛?如果函数内部的代码实际可能throw,那么我还应该让它不抛?
这是一个例子:
void swap(Type t1, Type t2) throw()
{
//swap
}
Run Code Online (Sandbox Code Playgroud)
如果代码中swap根本不会抛出,我还应该追加throw()吗?为什么?
/* user-defined exception class derived from a standard class for exceptions*/
class MyProblem : public std::exception {
public:
...
MyProblem(...) { //special constructor
}
virtual const char* what() const throw() {
//what() function
...
}
};
...
void f() {
...
//create an exception object and throw it
throw MyProblem(...);
...
}
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么在()之后有一个"const throw()"?通常,如果有一个throw(),它意味着throw()之前的函数可以抛出异常.但是,为什么抛出这里?
在C++中,您可以使用如下的异常规范声明函数:
int foo() const throw(Exception);
Run Code Online (Sandbox Code Playgroud)
我找到了这两个链接:
但有几件事最终没有答案......
问题1:为什么要添加异常规范?它会带来任何性能提升吗?编译器会有什么不同?因为它对我来说似乎就像程序员的信息.
问题2:如果我扔掉一些不符合规格的东西会发生什么(会发生什么)?例如:
int foo() throw(int) {
throw char; // Totally unrelated classes, not types in real
}
Run Code Online (Sandbox Code Playgroud)
问题3:函数/方法不应该抛出任何东西.我找到了至少两个(三种,不同编译器的替代语法)方法来指定无异常抛出:
int foo() throw();int foo() __attribute(nothrow)__ 对于gccint foo() nothrow 用于Visual C++哪一个是"正确的"?有什么区别吗?我应该使用哪一个?
问题4: " 非标准例外" bad_alloc,bad_cast,bad_exception,bad_typeid和ios_base::failure.
好的bad_alloc是自我解释,我知道如何(更重要的是何时)使用它(添加到异常规范),但其他的呢?他们都没有真正响铃......他们与哪些"代码片段"相关联?喜欢bad_alloc与之相关new char[500000].
问题5:如果我有异常类层次结构,如下所示:
class ExceptionFileType {
virtual const char * getError() const = 0;
};
class …Run Code Online (Sandbox Code Playgroud) 似乎普遍接受的是,异常规范并没有像人们想象的那样有所帮助.但我想知道只使用std :: exception的规范是否是一个很好的折衷方案:
void someFunction()
throw ( std::exception );
Run Code Online (Sandbox Code Playgroud)
它记录了此方法/函数可能抛出异常的事实.
它将确保仅抛出从std :: exception派生的异常,而不是某些外来类,如std :: string或int.
那么,这会更好,然后根本没有任何规格吗?
更新:
关于运行时 - 开销:将其视为断言的使用.无论运行时开销如何,您都在使用断言,对吧?我知道你通常可以为发布版本禁用它们,所以可能更好的方法是将异常规范包装在一个宏中,这样你就可以为发布版本禁用它.就像是:
#ifdef DEBUG
#define THROW( exception ) throw ( exception )
#else
#define THROW( exception )
#endif
void someFunction()
THROW( std::exception );
Run Code Online (Sandbox Code Playgroud) 如何编写既有throw又有成员初始化列表的ctor定义?它是否正确?
ClassName::ClassName(int parameter): datamember_(parameter) throw(ExceptionType)
Run Code Online (Sandbox Code Playgroud)