2016-03-30 27 views
2

この問題は不思議そうです。いくつかのプラットフォームでビルドする必要があるコードがいくつかあるが、いくつかのプラットフォームではthread_localをサポートしていないため、boost :: thread_specific_ptrを代わりに使用したいと思っている。しかし、すべてのプラットフォーム(x86/x64/arm、debug/release、os、too many)に対してバイナリを作成するのは不愉快です。私ができるboost :: thread_specific_ptrをthread_local経由で実装することは可能ですか?

#if HAS_THREAD_LOCAL 
class thread_specific_ptr 
{ 
    ... // use thread_local to implement 
}; 
#else 
using boost::thread_specific_ptr 
#endif 

:それは私たちがよりエレガントクライアントコードを保つことができるようにthread_local経由thread_specific_ptrのIMPすることができます場合、私はのように私は、ヘッダファイルを持ちたい

(#ifdefのを避けるため)不思議

方法を見つけられないかもしれません、おそらくあなたができる、ありがとう。

+1

IMHOの最善の方法は「boost :: thread_specific_ptr」boost :: thread_specific_ptrはBoost.Threadでサポートされているすべてのコンパイラで動作する移植可能なメカニズムを提供しています。あなたがコピーを作成したくない場合は、ブーストコードをコピーしてください(痛いです!) –

答えて

1

を使用してthread_specific_ptrを実装することは可能です。重要なのは、thread_localがストレージ指定子であり、thread_specific_ptrがオブジェクトであることです。したがって、thread_specific_ptrオブジェクトを動的に作成して破棄することは技術的に可能ですが、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_ptrthread_localより低いレベルのインターフェイスを使用するので、それは実際にいくつかのプラットフォーム上でboost::thread_specific_ptrより少し遅くすることができること。 boost::thread_specific_ptrが直面している問題を解決する必要があります。地図内の値を探すためにどのようなキーを使用するかなどです。しかし、このアプローチは、依存関係を取り除くことが目的の場合に便利です。

関連する問題