C ++イテレータリファレンスを返す

ヴェルナー

期待どおりに動作する例

#include <iostream>
#include <vector>

struct MyClass{


  const std::vector<float>::iterator& begin(){
    return myvec.begin();
  }

  const std::vector<float>::iterator& end(){
    return myvec.end();
  }
  std::vector<float> myvec;
};

int main(){

  std::vector<float> mainvec(8,0);

  MyClass myClass;

  myClass.myvec = mainvec;

  for (std::vector<float>::iterator it = myClass.begin();
      it != myClass.end();++it){
    std::cout << *it << " " ;
  }

  std::cout << std::endl;
}

このコードでは、次の出力が得られます。

0 0 0 0 0 0 0 0 

期待どおりに機能しない例:

#include <iostream>
#include <vector>

struct MyClass{


  const std::vector<float>::iterator& begin(){
    return myvec.begin();
  }

  const std::vector<float>::iterator& end(){
    return myvec.end();
  }
  std::vector<float> myvec;
};

int main(){

  std::vector<float> mainvec(8,0);

  MyClass myClass;

  myClass.myvec = mainvec;

  const std::vector<float>::iterator& end_reference = myClass.end();

  for (std::vector<float>::iterator it = myClass.begin();
      it != end_reference;++it){
    std::cout << *it << " " ;
  }

  std::cout << std::endl;
}

このコードでは、次の出力が得られます。

"empty output"

最初のコード例

それは私が起動する問題(誤って)ベクター有するbegin()end()代わりMyClassの方法のを。

私の疑問を表すために、次の最小限のコードがあります。

#include <iostream>
#include <vector>

struct MyClass{


  const std::vector<float>::iterator& begin(){
    return myvec.begin();
  }

  const std::vector<float>::iterator& end(){
    return myvec.end();
  }
  std::vector<float> myvec;
};

int main(){

  std::vector<float> mainvec(8,0);

  MyClass myClass;

  myClass.myvec = mainvec;

  for (std::vector<float>::iterator it = myClass.myvec.begin();
      it != myClass.myvec.end();++it){
    std::cout << *it << " " ;
  }

  std::cout << std::endl;
}

8行目と12行目に次の警告が表示されます。

returning reference to local temporary object [-Wreturn-stack-address] [cpp/gcc] 

しかし、プログラムをコンパイルして実行すると、次のようになります。

0 0 0 0 0 0 0 0 

したがって、ローカル参照は、を返すときに破棄されないようですmyvec.begin()私が最初にコードを書いたとき、それが問題になるとは思っていませんでした。私の頭の中では、ベクトルからのbegin()メソッドが最初のベクトルの場所へのイテレータ参照を返すので、このイテレータはそうではありません。 myvec.begin()を実行するときに割り当てられますが、このイテレータへの参照です。したがって、メモリを割り当てていないため、この警告は表示されないはずです。しかし、このメカニズムがどのように機能するかわからないので、一貫性のあるコードを書くためにそれを学びたいと思います。この警告は無視できるようですよね?

log0

std :: vector :: beginは確かに一時オブジェクトを返します(http://www.cplusplus.com/reference/vector/vector/begin/を参照

一時オブジェクトをconst参照にバインドし(非const参照では有効ではない)、ローカル変数にすぐにコピーするため、コードは有効ですit
編集:私の間違い。これは確かに、一時的なものからconst参照を返すUBでもあります。

ただし、この参照をより長い存続期間を持つ別のconst参照に割り当てると、一時オブジェクトの存続期間が直接割り当てられているconst参照の存続期間まで延長されるため、未定義の動作が発生します。

警告を考慮して、イテレータを返すことをお勧めします。

http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/も読むことをお勧めします

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

C ++用語リファレンスおよびイテレータ

分類Dev

c ++ラムダを関数ポインターリファレンスにコピーする

分類Dev

C#-MSBuildリファレンス-<itemGroup>のすべてのアイテムをCopyToOutputDirectoryにコピーします

分類Dev

C#リファレンスドキュメントをインテリセンスで表示する

分類Dev

C ++のテンプレート/リファレンス

分類Dev

C ++リファレンスをダウンロードする

分類Dev

C#ファクトリから汎用インターフェイスを返す

分類Dev

Typeが特定のインターフェイスを実装するクラスのすべてのプロパティを返すC#リフレクション

分類Dev

C ++-begin()は、空でないリストを含むend()イテレータを返します

分類Dev

リストをポインタとして渡すリストイテレータc ++

分類Dev

テンプレート化されたファンクターをテンプレートタイプ名として渡すC ++

分類Dev

C#リフレクションは、インターフェイスプロパティの実装プロパティを取得します

分類Dev

を使用したC ++テンプレートインターフェイス

分類Dev

C ++:ライブラリ内の多くのテンプレートをインスタンス化します

分類Dev

C#でのリフレクションにより、インターフェイスのベースインターフェイスを取得します

分類Dev

CLI / C ++インターフェイスクラス、テンプレートメソッドを呼び出すジェネリックメソッド

分類Dev

C ++で有効なイテレータを返す方法は?

分類Dev

c++: vector::insert からイテレータを返す

分類Dev

メソッドリファレンスの代わりにLambdaを使用したC#タイマー?

分類Dev

C#はグーグルカレンダーAPIからテキストファイルを書きます

分類Dev

レイジーイテレータを使用したC ++フィルタリング

分類Dev

C:テキストファイルから単一リンクリストにデータを追加する

分類Dev

C ++ゲッター一時vsconstリファレンス

分類Dev

Cファイルからテンプレート関数を呼び出す

分類Dev

C ++テキストフィルタリングテンプレートライブラリ/エンジン

分類Dev

C ++リストイテレータ演算

分類Dev

C ++リストイテレータ

分類Dev

C ++ :: #include:複数のソースファイルにテンプレートクラスヘッダーファイルを追加しますか?

分類Dev

リンクリストイテレータの実装C ++

Related 関連記事

  1. 1

    C ++用語リファレンスおよびイテレータ

  2. 2

    c ++ラムダを関数ポインターリファレンスにコピーする

  3. 3

    C#-MSBuildリファレンス-<itemGroup>のすべてのアイテムをCopyToOutputDirectoryにコピーします

  4. 4

    C#リファレンスドキュメントをインテリセンスで表示する

  5. 5

    C ++のテンプレート/リファレンス

  6. 6

    C ++リファレンスをダウンロードする

  7. 7

    C#ファクトリから汎用インターフェイスを返す

  8. 8

    Typeが特定のインターフェイスを実装するクラスのすべてのプロパティを返すC#リフレクション

  9. 9

    C ++-begin()は、空でないリストを含むend()イテレータを返します

  10. 10

    リストをポインタとして渡すリストイテレータc ++

  11. 11

    テンプレート化されたファンクターをテンプレートタイプ名として渡すC ++

  12. 12

    C#リフレクションは、インターフェイスプロパティの実装プロパティを取得します

  13. 13

    を使用したC ++テンプレートインターフェイス

  14. 14

    C ++:ライブラリ内の多くのテンプレートをインスタンス化します

  15. 15

    C#でのリフレクションにより、インターフェイスのベースインターフェイスを取得します

  16. 16

    CLI / C ++インターフェイスクラス、テンプレートメソッドを呼び出すジェネリックメソッド

  17. 17

    C ++で有効なイテレータを返す方法は?

  18. 18

    c++: vector::insert からイテレータを返す

  19. 19

    メソッドリファレンスの代わりにLambdaを使用したC#タイマー?

  20. 20

    C#はグーグルカレンダーAPIからテキストファイルを書きます

  21. 21

    レイジーイテレータを使用したC ++フィルタリング

  22. 22

    C:テキストファイルから単一リンクリストにデータを追加する

  23. 23

    C ++ゲッター一時vsconstリファレンス

  24. 24

    Cファイルからテンプレート関数を呼び出す

  25. 25

    C ++テキストフィルタリングテンプレートライブラリ/エンジン

  26. 26

    C ++リストイテレータ演算

  27. 27

    C ++リストイテレータ

  28. 28

    C ++ :: #include:複数のソースファイルにテンプレートクラスヘッダーファイルを追加しますか?

  29. 29

    リンクリストイテレータの実装C ++

ホットタグ

アーカイブ