db, err := sql.Open("postgres", "…")
if err != nil {
log.Fatalln(err)
}
defer db.Close()
tpl, err := template.ParseGlob("")
if err != nil {
log.Fatalln(err)
}
Run Code Online (Sandbox Code Playgroud)
如果template.ParseGlob("")返回错误,db.Close()仍然被调用?
我继续阅读该swap()操作,例如:
template<class T>
void swap (T &a, T &b)
{
T temp (a);
a = b;
b = temp;
}
Run Code Online (Sandbox Code Playgroud)
当我们处理异常安全时会出现问题.
它有什么问题?此外,我们如何解决它?
std::tie 返回一个引用元组,因此您可以执行以下操作:
int foo, bar, baz;
std::tie(foo, bar, baz) = std::make_tuple(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)
这与foo, bar, baz = (1, 2, 3)Python 类似.
如果其中一个分配抛出,应该发生什么,如下例所示?
int foo = 1337;
struct Bar {
Bar& operator=(Bar) { throw std::exception{}; }
} bar;
try {
std::tie(foo, bar) = std::make_tuple(42, Bar{});
} catch (std::exception const&) {
std::cout << foo << '\n';
}
Run Code Online (Sandbox Code Playgroud)
它会打印1337或42,还是未指定?
我正在使用 GCC 7.3.1,但也在coliru 上进行了测试,我认为它是 9.2.0 版。使用以下内容构建:
g++ -fsanitize=address -fno-omit-frame-pointer rai.cpp
Run Code Online (Sandbox Code Playgroud)
这是rai.cpp:
#include <iostream>
#include <unordered_map>
int main()
{
try
{
struct MyComp {
bool operator()(const std::string&, const std::string&) const {
throw std::runtime_error("Nonono");
}
};
std::unordered_map<std::string, std::string, std::hash<std::string>, MyComp> mymap;
mymap.insert(std::make_pair("Hello", "There"));
mymap.insert(std::make_pair("Hello", "There")); // Hash match forces compare
} catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
运行它的结果是:
> ./a.out
Caught exception: Nonono
=================================================================
==72432==ERROR: LeakSanitizer: detected memory leaks
Direct …Run Code Online (Sandbox Code Playgroud) 到目前为止,每个看过范围守卫都有一个保护布尔变量.例如,请参阅此讨论: 最简单,最新的c ++ 11 ScopeGuard
但是一个简单的守卫工作(gcc 4.9,clang 3.6.0):
template <class C>
struct finally_t : public C {
finally_t(C&& c): C(c) {}
~finally_t() { (*this)(); }
};
template <class C>
static finally_t<C> finally_create(C&& c) {
return std::forward<C>(c);
}
#define FINCAT_(a, b) a ## b
#define FINCAT(a, b) FINCAT_(a, b)
#define FINALLY(...) auto FINCAT(FINALY_, __LINE__) = \
finally_create([=](){ __VA_ARGS__ })
int main() {
int a = 1;
FINALLY( std::cout << "hello" << a << std::endl ; );
FINALLY( std::cout << "world" << …Run Code Online (Sandbox Code Playgroud) 我有一些代码需要线程安全和异常安全.下面的代码是我的问题的一个非常简化的版本:
#include <mutex>
#include <thread>
std::mutex mutex;
int n=0;
class Counter{
public:
Counter(){
std::lock_guard<std::mutex>guard(mutex);
n++;}
~Counter(){
std::lock_guard<std::mutex>guard(mutex);//How can I protect here the underlying code to mutex.lock() ?
n--;}
};
void doSomething(){
Counter counter;
//Here I could do something meaningful
}
int numberOfThreadInDoSomething(){
std::lock_guard<std::mutex>guard(mutex);
return n;}
Run Code Online (Sandbox Code Playgroud)
我有一个互斥锁,我需要锁定一个对象的析构函数.问题是我的析构函数不应该抛出异常.
我能做什么 ?
0)我不能n用原子变量替换(当然它会在这里做的但是这不是我的问题的重点)
1)我可以用旋转锁替换我的互斥锁
2)我可以尝试将锁定捕获到无限循环中,直到我最终获得锁定而没有异常引发
这些解决方案似乎都没有吸引力.你有同样的问题吗?你是怎么解决的?
我正在基于 2018 年后圣地亚哥草案 ( N4791 )实施我自己的向量,并且对实施强异常安全有一些疑问。
这是一些代码:
template <typename T, typename Allocator>
void Vector<T, Allocator>::push_back(const T& value)
{
if (buffer_capacity == 0)
{
this->Allocate(this->GetSufficientCapacity(1));
}
if (buffer_size < buffer_capacity)
{
this->Construct(value);
return;
}
auto new_buffer = CreateNewBuffer(this->GetSufficientCapacity(
buffer_size + 1), allocator);
this->MoveAll(new_buffer);
try
{
new_buffer.Construct(value);
}
catch (...)
{
this->Rollback(new_buffer, std::end(new_buffer));
throw;
}
this->Commit(std::move(new_buffer));
}
template <typename T, typename Allocator>
void Vector<T, Allocator>::Allocate(size_type new_capacity)
{
elements = std::allocator_traits<Allocator>::allocate(allocator,
new_capacity);
buffer_capacity = new_capacity;
}
template <typename T, typename Allocator> template <typename... …Run Code Online (Sandbox Code Playgroud) 第一个免责声明:这不是导致"语言战争".对于我的报告,我真的需要这个(关于这个主题的澄清),我只想拥有有效而坚实的论据.
好的,所以这里有一个问题:
在C++中,异常规范已从C++ 11标准中删除,因为它被认为造成了更多的伤害而不是好处.
另一方面,在Java中,异常规范被视为好的和有用的东西.
在这两种语言中,这两个概念(具有异常规范的目的)是不同的,这就是为什么它们被这两个社区看得不同或者那些概念是相似/相同的?
哪一个?异常规范是好事还是坏事?或者它在Java中很好,因为(在这里我想看到一些原因)并且在C++中很糟糕,因为(原因在这里).
感谢任何有建设性帮助的人.
我有一个类,其 ctor 进行驱动程序调用,其 dtor 进行匹配的终止/释放驱动程序调用。这些调用可能会失败。问题自然出在 dtor 身上。
我自然知道避免 dtor 中出现异常的常识,因为如果您在堆栈展开期间抛出异常,您会得到std::terminate. 但是 - 如果可以的话,我宁愿不只是“吞下”此类错误并且不报告它们。那么,编写这样的代码是否合法/惯用:
~MyClass() noexcept(false) {
auto result = something_which_may_fail_but_wont_throw();
if (std::uncaught_exceptions() == 0) {
throw some_exception(result);
}
}
Run Code Online (Sandbox Code Playgroud)
或者这只是巴洛克风格而不是一个好主意?
注意:此类无法访问标准输出/错误流,也无法访问日志等。
exception-safety ×10
c++ ×9
exception ×3
destructor ×2
c# ×1
c++20 ×1
containers ×1
gcc ×1
go ×1
idioms ×1
java ×1
raii ×1
scopeguard ×1
stl ×1