1

私はAcceleratec++の運動問題を解いていました。

§8.2.5/148で使用したスワップ関数を実装します。*begと*endの値を直接交換するのではなく、なぜスワップを呼び出すのですか?ヒント:試してみてください。

本の実際の機能は

template<class Bi> void reverse(Bi begin, Bi end) {
while (begin != end) {
       --end;
        if (begin != end)
           swap(*begin++, *end);
     } }

これに変えました

template<class Bi,class X> 
void reverse(Bi b, Bi e)
{
    X tmp;
    while (b!= e) {
        --e;
        if (b != e)
        {
           tmp=*b;
           *b=*a;
           *a=tmp;
            --b;
        }   
    }
}

そしてそれは動作しませんでした、次のエラーを出しました。

reverse(std :: vector :: iterator、std :: vector :: iterator)を呼び出すための一致する関数がありません '

私がこれに変えたより

template<class Bi,class X> 
void reverse(Bi b, Bi e,X c)
{
    X tmp=c;
    while (b!= e) {
        --e;
        if (b != e)
        {
           tmp=*b;
           *b=*a;
           *a=tmp;
            --b;
        }   
    }
}

上記の関数を次のように呼び出します

reverse(v.begin(),v.end(),0);

そしてそれは機能しました、しかし私はまだ2番目のものが機能しない理由を理解していませんでしたか?

4

2 に答える 2

2

コンパイラーはX、コードの内容を推測することはできません。ただし、イテレータに含まれるデータ型に追加のテンプレート型を指定する必要はありません。その正確な目的に役立つstd::iteratornamedというtypedefが含まれています。value_type

template<class Bi> 
void reverse(Bi b, Bi e)
{
    typename Bi::value_type tmp;
    while (b!= e) {
        --e;
        if (b != e)
        {
           tmp=*b;
           *b=*a;
           *a=tmp;
            --b;
        }   
    }
}
于 2012-04-22T15:47:51.277 に答える
1

問題は、新しく導入されたテンプレートパラメータXにあります。これは、引数に依存しないため、コンパイラによって決定できません。したがって、の呼び出し元はreverseそれを指定する必要があります。それらは明らかにそうではないので、コンパイラはコードを拒否します。

タイプは実際には関数に渡されるイテレータタイプに依存するため、typefromXを使用できます。ただし、これを行うには、ユーザーが関数で高レベルのイテレーターを使用する必要がありますが、これも実行したくありません。value_typeiterator_traitsreverse

C++11はdecltype同様の問題を解決する必要があります。ただし、多くのコンパイラがサポートしていないため、コードが新しい機能に依存することはおそらく望ましくありません。

また、コードはオブジェクトの不要なコピーを実行して、オブジェクトを一時変数との間で移動しています。これは、コピー演算子(またはコピーコンストラクター)がないと高レベルのオブジェクトでは機能しない可能性があります。C ++ 11でも、右辺値参照と移動セマンティクスがあります。しかし、それでも-デフォルトのコンストラクターがない可能性があるため、コードが壊れます。

理論的には、型特性を使用して渡されるオブジェクトの型を決定し、reverseテンプレートの特殊化を使用してさまざまな実装を考え出すことができますが、実際には...swap関数のオーバーロードを使用しているため、型を自動的に決定でき、Cの移動セマンティクスをサポートします++ 11など。たとえば、インライン化されておらず、要素ごとにフレームがプッシュ/ポップされた場合、これを使用すると問題が発生します。しかし、そうではありません。

また、swapそれ自体を専門にすることができます。たとえば、PODタイプの場合、XOR余分なコピーを作成せずに2つの要素のコンテンツを交換するために使用できます。とにかく現代のコンパイラはあなたのためにそれをします、しかしただの考え...

だからあなたはswap:)を使うほうがいいです

于 2012-04-22T15:55:53.790 に答える