2017-10-30 9 views
1

私は、コードのこの部分に出くわし、それを理解しようとしているが、特定のセクションでは、ループのための明確ではなく、次のとおりです。はループために凝縮。..(C++)

forward_list<Class> obj; 
auto b_end = obj.before_begin(); 

for (auto& _ : obj) 
    ++b_end ; 

obj.insert_after(b_end, Class newObj); 

ないループのために何をしているかを正確に確認してください。 forループを壊して理解するのに役立つかもしれませんか?

編集: この質問は重複して表示されていますが、他のスレッドは十分な情報を提供していない、および/または古すぎます。

+1

後の値3を追加することができます得たイテレータを使用して

-for) – rustyx

+0

私は完全なコードを投稿することはできませんが、コードの目的は、リストの最後にnewObjを常に挿入することです(技術的には最後ではなく、終わりの前にnullptrを指すかもしれませんか?) – Jin

+2

@Jin:A [mcve]は完全なコードではありません。それはおもちゃの例を作り、あなたが見る行動を再現することです。デバッグと理解のための非常に便利な演習です。 – AndyG

答えて

1

std::forward_listは、forward_iteratorsを持つシーケンシャルコンテナです。これは片側の単独リンクリストです。値をリストに挿入するには、メソッドinsert_afterのみを使用して、[begin(), end())の範囲内のイテレータを指定するか、before_begin()メソッドによって返されるイテレータを使用します。 C++規格から

5要件:位置before_begin()又は範囲内dereferenceable イテレータである[()、終了())を開始します。

リストの最後に新しい値を追加する場合は、リストの最後の要素に対応する位置にイテレータを移動する必要があります。

だから、このループは、名前付き範囲ベースのforループ

for (auto& _ : obj) 
    ++b_end ; 

移動は、リストの最後の要素によって占められる位置にステップ反復子b_endステップ。今度はイテレータを使用して、insert_afterというメソッドを使用してリストに新しい値を追加できます。

簡単なデモンストレーションプログラムを考えてみましょう。

#include <iostream> 
#include <forward_list> 

int main() 
{ 
    std::forward_list<int> lst = { 1, 2 }; 

    auto b_end = lst.before_begin(); 

    for (const auto &_ : lst) 
    { 
     ++b_end; 
     std::cout << *b_end << '\n'; 
    } 
    std::cout << std::endl; 

    lst.insert_after(b_end, 3); 

    for (const auto &_ : lst) std::cout << _ << ' '; 
    std::cout << std::endl; 

    return 0; 
} 

プログラムの出力は、リストの最初の要素の前に最初のイテレータb_endポイントで

1 
2 

1 2 3 

あります。リストが2つだけの要素が含まれているため、最初にイテレータが最初の要素に対応する位置に、次いで、第二に対応する位置に移動される2回の反復を有することになるループにおけるその後

auto b_end = lst.before_begin(); 
        ^^^^^^^^^^^^^^ 

素子。今、私たちはそれが[範囲ベースのforループ](http://en.cppreference.com/w/cpp/language/rangeと呼ばれる値2

1

この:

forward_list<Class> obj; 

objという名前Class -esのstd::forward_listを宣言します。コード中のどこかにusing namespace std;を使用しているため、std::の部分は省略されています。 この:

auto b_end = obj.before_begin(); 

は、あなたのobjリストにstd::forward_list::before_begin場所で指すイテレータを定義します。 は、この:

for (auto& _ : obj) 
    ++b_end; 

は参照渡し奇妙な名前の_変数を使用していますrange based for loopです。このループでは、b_endが各反復で増分されます。最後に :

obj.insert_after(b_end, Class newObj); 

b_end位置の後にタイプClassの新しいnewObjを挿入しようとすると、それはおそらくする必要がありますので、コンパイルに失敗します。

Class newObj; 
obj.insert_after(b_end, newObj); 

言われて、_は単なる変数であること名。それは(やや珍しい)有効な変数識別子です。

for (auto el : obj){ 
    ++b_end; 
} 

autoキーワードはauto specifierの略:全部は以下のように書き直されていることができるように、ここでは_変数自体はループのためにどのような方法で使用されていません。

関連する問題