C++ 17引入了std::shared_mutex
和std::scoped_lock
.我现在的问题是scoped_lock
,当它作为参数传递而不是在共享(读取器)模式下时,它将始终以独占(写入)模式锁定共享互斥锁.在我的应用程序中,我需要dst
使用来自对象的数据更新对象src
.我想锁定src
共享和dst
独占.不幸的是,如果同时调用另一个带有src
和dst
切换的更新方法,则可能会出现死锁.所以我想使用花哨的死锁避免机制std::scoped_lock
.
我可以使用scoped_lock
锁定src
和dst
独占模式,但不必要的严格锁具有其他地方的性能退缩.然而,现在看来,这是可能的包裹src
的shared_mutex
进入std::shared_lock
和使用,用scoped_lock
:当scoped_lock
其锁定在行动电话try_lock()
上shared_lock
,以后将实际调用try_shared_lock()
上src
的shared_mutex
,而这正是我需要的.
所以我的代码看起来很简单:
struct data {
mutable std::shared_mutex mutex;
// actual data follows
};
void update(const data& src, data& dst)
{
std::shared_lock slock(src.mutex, std::defer_lock);
std::scoped_lock lockall(slock, dst.mutex);
// now can safely update dst …
Run Code Online (Sandbox Code Playgroud) 这是一个奇怪的,我不知道,如果它是C++标准,我的编译器(Ubuntu 12.04上的G ++版本4.6.3,这是Ubuntu的最新长期支持版本)或我,谁不明白;-)
有问题的代码简单如下:
#include <algorithm> // for std::swap
void f(void)
{
class MyClass { };
MyClass aa, bb;
std::swap(aa, bb); // doesn't compile
}
Run Code Online (Sandbox Code Playgroud)
尝试使用G ++编译时,编译器会产生以下错误消息:
test.cpp: In function ‘void f()’:
test.cpp:6:21: error: no matching function for call to ‘swap(f()::MyClass&, f()::MyClass&)’
test.cpp:6:21: note: candidates are:
/usr/include/c++/4.6/bits/move.h:122:5: note: template<class _Tp> void std::swap(_Tp&, _Tp&)
/usr/include/c++/4.6/bits/move.h:136:5: note: template<class _Tp, long unsigned int _Nm> void std::swap(_Tp (&)[_Nm], _Tp (&)[_Nm])
Run Code Online (Sandbox Code Playgroud)
令人惊讶的结果是,只是将类定义移出函数使得代码编译正常:
#include <algorithm> // for std::swap
class MyClass { };
void f(void)
{
MyClass …
Run Code Online (Sandbox Code Playgroud) 我有一个函数f()
,它返回std::pair<A, B>
具有某些类型A
和B
. 我还有另一个函数g()
,它调用f()
两次并返回一个std::tuple<A, B, A, B>
. 有没有办法tuple
直接从两个调用构造返回f()
?所以我想将当前代码的最后三行作为快捷方式:
std::tuple<A, B, A, B>
g(type1 arg1, type2 arg2, ...) {
// perform some preprocessing
auto pair1 = f(...);
auto pair2 = f(...);
return { pair1.first, pair1.second, pair2.first, pair2.second }
}
Run Code Online (Sandbox Code Playgroud)
成一个班轮(而不是三个)。如果该解决方案也适用于任意长度的元组,那就太好了,尤其是在模板情况下。
例如,在当前的 Python3 中,解决方案是return (*f(...), *f(...))
. C++ 中是否有与 Python 中类似的列表/元组解包运算符?
在 C++ 中,如果直接创建对象,则可以将一次性结构和类声明为未命名:
struct { int x; int y; } point;
Run Code Online (Sandbox Code Playgroud)
未命名的类也可以从基类继承。例如,这对于从基本处理器接口创建不同“处理器”的列表很有用。这是一个简单的例子:
struct Processor {virtual int op(int a, int b) = 0;};
struct : Processor {int op(int a, int b) override { return a+b; }} Adder;
struct : Processor {int op(int a, int b) override { return a*b; }} Multiplier;
Run Code Online (Sandbox Code Playgroud)
因此Adder
和 都Multiplier
成为接口的单个派生对象Processor
。但是,如果基础处理器具有更多结构并且具有需要参数的构造函数,该怎么办?让我们看这个例子:
class Processor {
private:
std::string name;
public:
virtual int op(int a, int b) = 0;
const std::string& getName() const { return name; …
Run Code Online (Sandbox Code Playgroud) c++ inheritance constructor default-constructor unnamed-class
c++ ×4
constructor ×1
deadlock ×1
inheritance ×1
scoped-lock ×1
std ×1
std-pair ×1
stdtuple ×1
swap ×1