1

構造体要素を含むベクトルの適切なサイズを取得するのに問題があります。要素クラスは次のように定義されます(唯一の関連する事実は、intと2つのdoubleを含むクラスであると思いますが、詳細は省略しませんでした):

class Interval
{
public:
    Interval(int _i = 0, scalar _l = 0, scalar _r = 0) :
        index(_i),
        l(_l),
        r(_r)
    { }

    inline double left(void)    const { return l; }
    inline double right(void)   const { return r; }

    inline bool operator < (const Interval & i2) const { return left() < i2.left(); }

public:
    int index;
    double l;
    double r;

};

次に、関数に次のコードがあります。

std::vector<Interval> arr(10);
int s1 = arr.size();
int s2 = arr.end() - arr.begin();

私が得るs1の値は15ですが、s2は正しい値10です。何が起こっているのでしょうか。size()は正確に要素の数を返すことになっているのではありませんか?arr.end()-arr.begin()と同じではないですか?

任意の応答とコメントをいただければ幸いです。

4

4 に答える 4

1

まず、コードをフォーマットするときにHTMLタグの使用を停止します。代わりに[コード]ボタンを使用してください。

第二に、あなたが説明するのは、説明に反する謎です。10との両方で同じ値を取得する必要がs1ありs2ます。それは、他のコードでベクトルの整合性をなんとか破壊した場合を除きます(つまり、実行するコードは、表示するコードではありません)。

于 2010-10-31T04:19:42.647 に答える
1

コードパッドで期待どおりに機能する

于 2010-10-31T05:56:55.327 に答える
0

更新:プロジェクトのコードベースを調べた後、他の人が書いた別のヘッダーに「Interval」という同じ名前の別のクラスが見つかりました(クラス名のような単純な単語を選んだのは残念です)。そのクラスには2つのdoubleが含まれています(私のマシンでは16バイトですが、私のクラスには24バイトがあります)。これは、size()呼び出しが実際の要素数よりも50%多い理由を説明しているようです。

しかし、std :: vectorが2つの定義によってどのように混同される可能性があるのか​​わかりません(コードにそのヘッダーを含めませんでしたが、ヘッダーを含めた後、ヘッダーはプロジェクトの他の部分に含まれる可能性があります)。 end()-begin()が1つの定義を使用し、size()が別の定義を使用する方法。

ところで、マルチプログラマープロジェクトでこのような衝突を回避するには、名前空間を使用するのがベストプラクティスですよね?ありがとう。

于 2010-10-31T15:33:35.030 に答える
0

編集:あなたがより多くの情報を提供したので、おそらく私たちはこの紛らわしい振る舞いにいくらかの光を当てることができます。

単一定義規則に違反しました。これを行った結果は実際には定義されていませんが、観察された結果に基づいて、知識に基づいた推測を行うことができます。

テンプレート関数は、テンプレートパラメータの置換に必要なため、常にインラインで宣言されます。コンパイラーがこれらの関数の1つに遭遇すると、それをインラインコードとして発行するか、関数本体を作成して呼び出すかを選択できます。関数本体を作成する場合、リンカは異なる変換単位で重複する定義を排除する責任があります。リンカは、見かけの重複が機能的に同等であるかどうかを確認するために多くのチェックを行いません。引数のタイプに応じて、関数の装飾された名前を使用するだけです。タイプがすべて同じ名前である場合、それらは同一であると見なされます。単一定義規則により、この仮定を行うことができます。

これは、ソースに含まれていないクラス定義をコードの結果に影響を与える方法です。リンカーは、コードの不良コピーを適切なコピーに置き換えています。コンパイラーがインラインコードを生成する場合、期待する結果が得られます。リンカーが関与する場合、間違ったものを取得する可能性が50/50になります。そして、あなたのコードが幸運になったとしても、他のコードが破壊されています。


元の回答:ベクトルが要求されたサイズよりも大きくなる可能性がsizeありますが、その値は反映されません。を使用してこれをテストできますcapacity。余分なストレージはメモリ使用量の一部になりますが、要素は初期化されず、の結果を超えてアクセスしようとするとsize、未定義の動作が発生します。

于 2010-10-31T04:33:07.540 に答える