2012-03-13 2 views
3

pp. 8rawポインタを入れ替えるためにboost :: swapを使用しますか?

フリー機能

template<typename T> void swap(scoped_ptr<T>& a,scoped_ptr<T>& b) 

に基づいて、この関数は、2つのスコープポインタの 内容を交換することにより、好ましい手段を提供しています。ローポインタとサードパーティのスマート ポインターを含む多くのポインタータイプに対して swap(scoped1、scoped2)を一般的に(テンプレートコードで) に適用できるので、 scoped1.swap(scoped2)は、生ポインタ上の ではなく、操作を定義するスマートポインタに対してのみ機能します。

int* pA = new int(10); 
int *pB = new int(20); 

boost::swap(pA, pB); // Error: could not deduce template argument for 'boost::scoped_ptr<T> &' from 'int *' 

質問>どのようにboost::swapと生のポインタを交換するには?

+0

コードスニペットはあなたのものか本のものか。 – GManNickG

答えて

4

他の回答があなたにboost::swapを使用しないように指示している理由がわかりません。 目的をすべてboost::swapusing std::swap; swap(x, y);のビジネスを非表示にすることです。これはうまく動作します:

#include <boost/swap.hpp> 

int main() 
{ 
    int* pA = new int(10); 
    int *pB = new int(20); 

    boost::swap(pA, pB); 

    delete pA; 
    delete pB; 
} 

を明らかにあなたがboost/swap.hppが含まれていない場合、これは動作しません。これは、boost::swapを使って2つのものを交換する方法です。あなたは常にこの形式で2つのものを交換することを好むべきです!

何を読んでいることは、単にこれはあまりにも動作するようにboost::scoped_ptrも、boost名前空間内のswapの過負荷を提供することを述べている:

#include <boost/scoped_ptr.hpp> 

int main() 
{  
    boost::scoped_ptr<int> pA(new int(20)); 
    boost::scoped_ptr<int> pB(new int(20)); 

    boost::swap(pA, pB); 
} 

しかし、動作しないことを明確にする必要があります:

#include <boost/scoped_ptr.hpp> 

int main() 
{ 
    int* pA = new int(10); 
    int *pB = new int(20); 

    boost::swap(pA, pB); 

    delete pA; 
    delete pB; 
} 

boost/scoped_ptr.hppが提供されていない(そして実際に提供する責任はありません)boost::swapの一般的な実装をするので。そのような

#include <boost/scoped_ptr.hpp> 
#include <boost/swap.hpp> 

int main() 
{ 
    int* pA = new int(10); 
    int *pB = new int(20); 

    boost::scoped_ptr<int> pC(new int(20)); 
    boost::scoped_ptr<int> pD(new int(20)); 

    boost::swap(pA, pB); 
    boost::swap(pC, pD); 

    delete pA; 
    delete pB; 
} 

:あなたは、一般的でboost::swapを使用したい場合は、boost/swap.hppを含める必要があります。あなたができるBoostを持っているなら、std::swapものを使用することにフォールバックしないでください。

4

これは、スワップイディオム、またはユーザーコードによってスワップがどのように実装されるべきかを示しています。メンバーm1のセットがあり、名前空間NでタイプT ... mNためswapを実現するための推奨される方法は次のとおりです。

namespace N { 
    void swap(T& lhs, T& rhs) { 
     using std::swap; 
     swap(lhs.m1, rhs.m1); 
     ... 
     swap(lhs.mN, rhs.mN); 
    } 
} 

イディオムは、ADL(引数依存の照合)を利用しています。最初にstd::swapという定義がスコープに挿入されるため、の特定の要素に対して、より良いオーバーロードが存在しない場合に利用できます。その後、mnメンバーのいずれかのタイプのTnがフリー機能スワップを定義している場合、ADLはスコープにそれをもたらすと専門のswapではなくstd::swapよりも使用されることを知って、資格のない自由な機能swapを使用しています。上記のイディオム以下scoped_ptrオブジェクトを含む任意の要素を交換する

どのようなドキュメントが言っていることは、あなたがptr1.swap(ptr2)を呼ぶべきではないということですが、むしろ資格のないswap(ptr1, ptr2)。つまり、スワップを実装すると、ポインタが生ポインタまたはscoped_ptrのいずれかであるかどうかなど、メンバータイプが変更されているため、swap関数を変更する必要はありません。

+0

テンプレート以外のテンプレートは、オーバーロード解決時に常にテンプレートより優先されるため、名前空間スコープのテンプレート以外のスワップがboost :: swapとstd :: swapの両方よりも優先されます。 [参照](http://stackoverflow.com/a/6115281/391104) – q0987

+0

引数依存ルックアップ(ADL)、または引数依存の名前検索[ADL](http://en.wikipedia.org/wiki/Argument -dependent_name_lookup) – q0987

+0

ポインタを入れ替えるのに 'boost :: swap'を使わないのはなぜですか?その存在のポイントは、 'std :: swap'を使う必要がないことです。 – GManNickG

関連する問題