问题描述
我试图找到一种方法来设置没有构造函数/析构函数(int,byte,long等)作为原子操作的POD。
我需要的原因是因为我想使用__declspec(线程)为了有一个TLSint作为线程本地存储。事情是,目前的VC ++编译器不支持具有构造函数/析构函数的对象,所以我声明:
static __declspec )int _thread_val;
接下来,我要设置 _thread_val
使用std :: atomic不工作,因为它有构造函数/析构函数,因此不支持:
static __declspec(thread)std :: atomic< int> _thread_val; //不在VC ++中编译
我也在VC内部函数中查找,
有没有人知道如何做?
不幸的是,Microsoft的实现 std :: atomic< T>
是不符合通过没有一个琐碎的默认构造函数。你可以通过使用包装类来解决这个问题。因为你知道 std :: atomic< T>
在没有被构造时应该是可用的(因为你知道它应该是一个POD类型) ,也不需要破坏,你可以使用 std :: aligned_storage
来保存对象。这是一个起点,它可能需要轻微调整取决于你会遇到的编译器特定的怪癖。
template< typename T>
class atomic_wrapper
{
std :: aligned_storage< sizeof(std :: atomic< T>),alignof(std :: atomic&数据;
public:
atomic_wrapper()= default;
atomic_wrapper(const atomic_wrapper< T>&)= delete;
std :: atomic< T> & operator *(){return reinterpret_cast< std :: atomic< T> &>(data); }
std :: atomic< T> * operator - >(){return& ** this; }
};
现在,不是将变量声明为 std :: atomic< int> a;
,声明为 atomic_wrapper< int> a;
,并更新您的访问以使用 * a
而不是 a
p>
I am trying to find a way to set a POD that doesn't have constructor/destructor (int, byte, long etc.) as atomic operation.
The reason I need that is because I want to use __declspec(thread) in order to have a TLS "int" as a thread local storage. The thing is that current VC++ compiler doesn't support objects that have constructor/destructor, so I declared:
static __declspec(thread) int _thread_val;
Next, I want to set that _thread_val
atomically.
Using std::atomic doesn't work because it has constructor/destructor, therefore it is not supported:
static __declspec(thread) std::atomic<int> _thread_val; //doesn't compile in VC++
I also looked in VC intrinsic functions, but didn't find exactly what I wanted (guess due to lack of documentation).
Does anyone know how to do it?
It is unfortunate that Microsoft's implementation of std::atomic<T>
is non-conforming by not having a trivial default constructor. You may be able to work around that by using a wrapper class. Since you know that std::atomic<T>
is supposed to be usable when it hasn't been constructed (since you know that it is supposed to be a POD type), and doesn't require destruction either, you can use std::aligned_storage
to hold the object. Here's a starting point, it may need slight tweaking depending on the compiler-specific quirks you'll encounter.
template <typename T>
class atomic_wrapper
{
std::aligned_storage<sizeof(std::atomic<T>), alignof(std::atomic<T>)> data;
public:
atomic_wrapper() = default;
atomic_wrapper(const atomic_wrapper<T> &) = delete;
std::atomic<T> &operator *() { return reinterpret_cast<std::atomic<T> &>(data); }
std::atomic<T> *operator ->() { return &**this; }
};
Now, instead of declaring a variable as std::atomic<int> a;
, declare it as atomic_wrapper<int> a;
, and update your accesses to use *a
instead of a
.
这篇关于在VC ++中的1个原子操作中,将值设置为POD(不具有构造函数/结构体)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!