C+11とBoost


2013年10月11日18:05 Jens Wellerより発表されました.
C+11の標準ライブラリのいくつかの部分は、Boostの中で標準ライブラリより先にある.C++11をプレイする時、標準ライブラリの中のいくつかの部品を使うことに慣れます.これらの部品はC+03の中でそのBoostの対応部分と一緒に使います.また、現在はC+11ベースのライブラリもいくつか出現していますので、BoostまたはC+11コードとのインターフェースはすぐに問題になります.
BoostはすでにC+03で長年使われていますので、C+11のBoostバージョンを使うのは自然な選択です.これらのバージョンは今stdです.C+03とインタフェースできるようにします.しかし、いくつかの人は喜んでC+11を使うことができます.この二つの立場はどの程度においても混合されており、一つとして間違っているものはない.それでも、C+11を使うことが多くなりました.いろいろなところを見始めました.そして、どのように「古い」Boostと「新しい」C++タイプの間でインターフェースをするかを常に考えています.
C++の発展とともに,特にライブラリの特性はある程度のBoostを得ることができた.Boost:ファイルシステムは今すでに存在している最も明白なライブラリで、標準化されています.すぐにTSになります.C+1 Yの一部かもしれません.スレッドは、将来を提供しています.これにより、マージ用のTSは、Boost中のアクチュエータとタスクに基づく並列化ライブラリをもたらすことになります.C+++標準化には時間がかかりますが、Boostはより速く移動し、より早く特性を実現し、その後が標準的な特性です.実際、Boostの最後のバージョンは主にC+11、F.Eを採用しています.スレッドは現在、std:スレッドのようなインターフェースを提供しています.
だから、このブログの記事では、確かにBoostを確認しました.和std:function、およびstd:スレッド/Boost:スレッドは、Boostテンプレートで使用される概念を確認します.例えば、ロック可能です.このコードはテスト用です.現実生活ではより複雑なコードの中で発生します.おそらくあなたには見えないかもしれません.すべてのテストコードはGCC/MinGW 4.8でコンパイルされます.
機能のいくつかの混合Boost:とstd:Functionのテストコード:
void myFunc()
{
    std::cout << "myFunc" << std::endl;
}

void bFunc(boost::function bfunc)
{
    bfunc();
}

void stdFunc(std::function stdfunc)
{
    stdfunc();
}

struct foo
{
    int i;
    foo(int i):i(i){}
    void bar(int x){ std::cout << "foo::bar " << i << " " << x <<:endl/>
ですから、これはテスト設定です.このテストを使いたいのですが、私はタイプを交換できますか?多くのコードは、Boost:Functionをコールバックタイプに使用しています.例えば、Boost:Functionはstd:functionの一例を除いていますか?テストしましょう
std::function stdfunc = myFunc;//std::bind(myFunc);
boost::function bfunc = myFunc;

bFunc(stdfunc);
stdFunc(bfunc);

foo f(4);
std::function cstdfunc = std::bind(&foo::bar,&f,23);
boost::function bstdfunc = boost::bind(&foo::bar,&f,23);

bFunc(cstdfunc);
stdFunc(bstdfunc);
ですから、関数から始まります.ちょっと特殊なタイプから始めます.バックグラウンドでは、多くの異なるものをラッピングできるように、タイプを使って消去します.これは上のコードをコンパイルして作業することができます.Const以外の引用だけは機能しません.C++は実際にはあなたのタイプが間違っていると教えてくれます.明らかにいくつかの魔力があって、これは実行可能で、もしそれはいかなる利益があるならば別の問題です.このタイプは、新しいインスタンスにBoostまたはstdタイプをカプセル化し、これは、呼び出しレベルの新しいレベルをもたらします.
「どんないい問題でも」という答えは実際には否定的です.このような状況をできるだけ避けるべきです.上のコードで新しいタイプの包装ができます.毎回このようにすると、新しい包装レベルが追加されます.そのため、毎回このようにして、間接的にあなたの電話に新しいレベルを追加しました.またはSTL参照:
Boostから:Functionからstdを構築します.Functionまたは逆の関数は怖いです.2倍の罰を与えます.STLのメンテナとして、私が欲しい以上に泣きたいです.
だから、それが働いているだけで、あなたがそうするべきだという意味ではありません.
ここはスマートポインタが面白いです.例えば、Shared_PTRは標準とBoostの間のタイプ境界でインターフェースを行うことができない.また、UNIQUE_PTRは標準では唯一であり、Boostはスコープを提供している.PTR標準とBoostのスマートポインタのバージョンです.違います
一つはShared_に使われますPTRの短い例:
std::shared_ptr std_shared = std::make_shared(5);
boost::shared_ptr bshared = std_shared;
これは不可能です.この場合,最も明白な解はTypeTに依存し,挙動を実現させ,例えばクローン法とすることができる.そのため、BoostのShared_PTRは新しいコピーの新しい所有権を占有する可能性があります.引越しは有効な策略かもしれませんが、私にとって邪悪な感じです.
しかし、エリック・ニブルが指摘したツイッターのように、両者の間にポインタを交換する解決策があります.
template
boost::shared_ptr make_shared_ptr(const std::shared_ptr& ptr)
{
    return boost::shared_ptr(ptr.get(), [ptr](T*){});
}

template
std::shared_ptr make_shared_ptr(const boost::shared_ptr& ptr)
{
    return std::shared_ptr(ptr.get(), [ptr](T*){});
}
この解決策の利点は、他のすべてのオリジナルコピーが破棄された場合、削除器に含まれるオリジナルのShared_PTRはアクティブ状態を維持します.したがって、常に針は有効であると保証されます.
同じShared_PTR上、Boost:Shared_PTR!=std:Shared_PTR二つのバージョンはほとんどのインターフェースを共有しますが、他のバージョンがサポートされていない方法を追加します.Std:Shared_PTRはすでに分配されましたSharedとget_削除します.この両方はBoostに追加できます.Boostバージョンは配列をサポートしていますが、標準バージョンはカスタム削除器のみをサポートしています.これは論争がある場合、Shard_PTRは配列をサポートするべきであり、それは実際には容器ではないので、配列にとってBEGIN()/End()が良い選択となる.
UNIQUE_を使用するPTRの場合は少し違っていますが、呼び出し側の指針の所有権を与えるリリース方法があります.したがって、UNIQUEを一つ使ってもいいです.PTRはBOOSTでアクティブドメイン_を初期化する.PTRはこのようにして所有権を失いました.しかしこれは一方向の解である.Scope_PTRは永遠に所有権を放棄しません.したがって、オブジェクトを転送するには、クローン方法/コピーが必要です.UNIQUE_に使用するPTRのカスタム非削除器はソリューションだけです.もしその生存期間がスコープよりも大きいならば.ptrが短い.しかし、なぜ続けて進めないですか?
私は元のグループだけを見ました.元のグループの人ではないので、stdが好きです.促進:元のグループはもうしばらくの間存在していますので、未来に会うことはあまりありません.このようなコードがいいです.
std::tuple stdtuple=std:make_tuple(1,2,3)book:tuple btuple=stdtuple;しかし、少なくともBoost 1.54の場合は、これは通用しません.同様に、それを作業させるのは最高のアイディアではないかもしれません.したがって、tupleは良い例であり、Boostと標準タイプの間に不一致が存在している.しかし、これは明らかに大きな事故ではありません.この差を克服するには、いくつかのベニヤ板を作成するか、コードにC+11のタイプを受け入れる追加インターフェースを追加します.
ねじは私達にBoostとstdを混合させます:スレッドコード、見たところ良い考えではありません.スレッドは良い例です.標準ではなくBoostがもっと好きです.もう一つは「レゲックス」です.10月13日にGCCで全面的に実施されたばかりです.しかし、いくつかのコードはテンプレートにおいてロックなどの概念を使用しています.私の考えでは、これらの概念はstdを許可します.Gardロック.すべてのタイプがテンプレートパラメータであれば大丈夫です.しかし一つのstd:mutexはいつも異なるリソースを割り当てて、その後Boost:mutex.Boostはこのセクションで明らかな利点を持っています.これは非常に有用なもの(SharedmuttexesF.E.)を実現できますが、C+11はこれらの機能を備えていません.したがって、この例では、Boost:スレッドを使用すると、並列性を使用する場合には、タスクベースのソリューションが使用されると思う.本当に自分が何をしているかを知っているときにのみ、ローレベルロックのコードを作成することができます.ロックが相互にロックされるたびに、デッドロックに陥る可能性があります.これは低レベルスレッドの問題を指摘するためだけです.
おわりにはどうすればいいですか?すべてのソリューションに適合する人はいません.あなたのコードライブラリでBoostを使用すると、それを使用し続けるかもしれません.Boostタイプと標準タイプとの間のインターフェースはしばしば難しい.この場合、Boostはサポートstdを採用して追加することができます.この問題に直面する時、ユーザーは通常このようにしなければなりません.一方、シェアハウスPTRはコードの原因となりますが、二つの異なるコピーが並列に存在してもいいです.概念/インターフェースを使用する一般テンプレートコードは問題をある程度回避できるが、部分的な解決策にすぎない.
Boostの大きな利点は、各関連プラットフォームにおいて同じ実装を使用することである(ただし、異なるバックエンドOFCがある場合がある).したがって、現在はC++14>1 Y>YZに進むと、Boostはいくつかのライブラリの初期バージョンを提供するかもしれない.Boost:別のいい例があります.
したがって、コードライブラリについては、どのような規則を設定するかを決めなければなりません.どのバージョンを使用しますか?あなたのコードを混合または再構成することはC+11の標準には不可能です.C+03は生産中ですので、長年使っています.現在使用されている標準のタイプのみを使用すると、Boostを削除することもできます.これは依存項を減らすことになります.しかし、Boostはこのように多くのライブラリを提供しています.これらのライブラリは未来の標準の一部ではありません.だから、遅かれ早かれ、Boostをもう一度あなたのコードライブラリに導入したいかもしれません.
今後はBoostがC++11の標準ライブラリタイプからそのタイプに変換するためにどれだけの解決策を提供するかを示すだろう.Boostは自分のタイプを放棄しないはずです.だからこの問題は依然として存在しています.特にC++標準に従ってさらに新しい水域に発展します.