这个问题可能看起来很奇怪。我想这样做是因为我们需要在几个平台上构建一些代码,但是某些平台不支持thread_local,而是使用boost :: thread_specific_ptr。然而,为每个平台(x86 / x64 / arm,debug / release,os,太多)构建boost二进制文件是令人不快的。
我想知道是否可以通过thread_local来破坏thread_specific_ptr,以便我们可以保持客户端代码更优雅(避免#ifdef)
我想要一个头文件,如:
#if HAS_THREAD_LOCAL
class thread_specific_ptr
{
... // use thread_local to implement
};
#else
using boost::thread_specific_ptr
#endif
我无法找到方法,也许你可以,谢谢。
答案 0 :(得分:1)
可以使用thread_specific_ptr
实施thread_local
。必须记住的重要部分是thread_local
是存储说明符,thread_specific_ptr
是对象。因此,在技术上可以动态创建和销毁thread_specific_ptr
个对象,而不能使用thread_local
个对象。例如,您不能将thread_local
对象作为您班级的成员。
但是,thread_local
可以在thread_specific_ptr
内部使用thread_specific_ptr
来根据当前线程选择内部结构。该结构可以包含程序中所有std::map
的数据,并允许动态创建和删除其元素。例如,可以使用thread_local std::map< void*, std::shared_ptr< void > > thread_specific_ptr_data;
template< typename T >
class thread_specific_ptr
{
public:
T* get() const
{
auto it = thread_specific_ptr_data.find(this);
if (it != thread_specific_ptr_data.end())
return static_cast< T* >(it->second.get());
return nullptr;
}
};
来实现此目的。
thread_local
当然,与原始使用boost::thread_specific_ptr
相比,这会增加一些开销,并且在某些平台上它实际上比boost::thread_specific_ptr
慢一点,因为thread_local
使用较低级别接口比boost::thread_specific_ptr
。您还必须解决select
CustomerName = (select
Customer.Name
from
Customers
where
Orders.CustomerId = Customer.Id),
Orders.OrderDate
from
Orders
面临的问题,例如用于在地图中查找值的键。但是,如果您的目标是删除依赖项,则此方法非常有用。