假设我们写了一些可以同时使用的新类。显然,我们不希望锁定所有可能同时被调用的东西。解决此问题的一种方法是通过mixins参数化指定锁定:
template<class Locking>
struct foo : private Locking {
void bar() {
Locking::read_lock();
// Do something.
Locking::read_unlock();
}
};
并使用实际锁定多线程情况的类来实例化Locking
,并使用对其他情况执行no-ops的类(希望编译器甚至可以优化掉调用)。
现在假设我想用软件事务内存而不是锁定来做这件事。看N3919(或gcc precursor),这个想法是不同的。没有诸如
之类的电话transaction_start();
transaction_end();
而是有像
这样的函数说明符void bar() transaction_safe;
和块说明符,如
transaction { /* body */ }
后者的严格规则称之为前者,mixins可以使用任何类似的内容。
如何做到这一点(没有涉及预处理器)?另请注意one of the main benefits of STM is composability,但似乎没有办法让实例化反映出bar
是可交易的。
答案 0 :(得分:1)
以类似的方式,使用lambda,您似乎可以执行以下操作:
template<class Transaction>
struct foo {
void bar() {
Transaction::run([](){ /* Do something. */ });
}
};
有两个实现
template<typename F>
void TransactionNone::run(F f) { f(); }
和
template<typename F>
void TransactionReal::run(F f) { transaction{ f(); } }
对于属性,
如果函数不是事务不安全的,则该函数是事务安全的。
所以你似乎可以省略那个关键字,让编译器/链接器完成这项工作。