std::vector

std::vector を試してみます。

 

 

 

1. 始めに (push_back)

[概要]

ja.cppreference.com に記載されているサンプルプログラムから作成してみます。
push_back() を使う例です。

https://ja.cppreference.com/w/cpp/container/vector

 

std::vector<T,Allocator>::push_back
void push_back( const T& value ); (1)
void push_back( T&& value ); (2)(c++11以上)

指定された要素 value をコンテナの終端に追加します。

(1) 新しい要素は value のコピーとして初期化されます。
(2) value が新しい要素にムーブされます。

新しい size() が capacity() より大きい場合は、すべてのイテレータおよび参照(終端イテレータを含む)が無効化されます。そうでなければ、終端イテレータのみが無効化されます。

引数
value - 追加する要素の値
戻り値
(なし)  

 

[環境]

コンパイラ : Visual Studio 2019 pro., Version 16.7.0
OS: Windows10 home, Version 1909

 

[プログラムソース]

#include <iostream>
#include <vector>
 
int main()
{
    // Create a vector containing integers
    std::vector<int> v = {7, 5, 16, 8};
 
    // Add two more integers to vector
    v.push_back(25);
    v.push_back(13);
 
    // Iterate and print values of vector
    for(int n : v) {
        std::cout << n << '\n';
    }
}
 

[出力]

7
5
16
8
25
13 

 

 

2. insert

[概要]

同じく ja.cppreference.com に記載されているサンプルプログラムから insert() による要素の挿入を行うサンプルを作成してみます。

https://ja.cppreference.com/w/cpp/container/vector/insert

 

std::vector<T,Allocator>::insert
iterator insert( iterator pos, const T& value ); (1) (c++11 未満)
iterator insert( const_iterator pos, const T& value ); (2) (c++11 以上)
iterator insert( const_iterator pos, const T&& value ); (3) (c++11 以上)
void insert( iterator pos, size_type count, const T& value ); (4) (c++11 未満)
iterator insert( const_iterator pos, size_type count, const T& value ); (5) (c++11 以上)
template< class InputIt >
void insert( const_iterator pos, InputIt first, InputIt last );
(6) (c++11 未満)
template< class InputIt >
iterator insert( const_iterator pos, InputIt first, InputIt last );
(7) (c++11 以上)
iterator insert( const_iterator pos, std::initializer_list<T> ilist ); (8) (c++11 以上)

コンテナ内の指定された位置に要素を挿入します。

(1-3) pos の前に value を挿入します。
(4-5) pos の前に value のコピーを count 個挿入します。
(6-7) pos の前に範囲 [first, last] から要素を挿入します。
(8) pos の前に初期化子リスト ilist から要素を挿入します。

新しい size() が capacity() より大きい場合は再確保が発生し、すべてのイテレータおよび参照(終端イテレータを含む)が無効化されます。そうでなければ、終端イテレータのみが無効化されます。

引数
pos - 前に内容が挿入されるイテレータ。pos は end() イテレータでも構いません。
value - 挿入する要素の値
first, last - 挿入する要素の範囲。insert が呼ばれたコンテナ内を示すイテレータは使用できません。
ilist - 挿入する値の初期化子リスト
戻り値
挿入された value を指すイテレータ。 (1-3)
挿入された 最初の要素を指すイテレータ、または count==0 の場合は pos。 (4-5)
挿入された 最初の要素を指すイテレータ、または first==last の場合は pos。 (6-7)
挿入された 最初の要素を指すイテレータ、または ilist が空の場合は pos。 (8)

 

 

[環境]

コンパイラ : Visual Studio 2019 pro., Version 16.7.0
OS: Windows10 home, Version 1909

 

[プログラムソース]

#include <iostream>
#include <vector>

void print_vec(const std::vector<int>& vec)
{
    for (auto x : vec) {
        std::cout << ' ' << x;
    }
    std::cout << '\n';
}

int main()
{
    std::vector<int> vec(3, 100);
    print_vec(vec);

    auto it = vec.begin();
    it = vec.insert(it, 200);
    print_vec(vec);

    vec.insert(it, 2, 300);
    print_vec(vec);

    // "it" no longer valid, get a new one:
    it = vec.begin();

    std::vector<int> vec2(2, 400);
    vec.insert(it + 2, vec2.begin(), vec2.end());
    print_vec(vec);

    int arr[] = { 501,502,503 };
    vec.insert(vec.begin(), arr, arr + 3);
    print_vec(vec);
}
 

[出力]

100 100 100
200 100 100 100
300 300 200 100 100 100
300 300 400 400 200 100 100 100
501 502 503 300 300 400 400 200 100 100 100

 

 

3. emplace_back (c++11)

[概要]

emplace_back を使った要素を挿入する例を示します。

emplace_back, emplace_front は c++11 以降で使用可能です。
push_back を使用したときに必要なコピーやムーブを回避するために、どのように emplace_back を使用すれば良いかを示します。

 

std::vector<T,Allocator>::emplace_back
template< class... Args >
void emplace_back( Args&&... args );
(1)(c++11以上)
template< class... Args >
reference emplace_back( Args&&... args );
(2)(c++17以上)

コンテナの終端に新しい要素を追加します。
新しい size() が capacity() より大きい場合は再確保が発生し、すべてのイテレータおよび参照(終端イテレータを含む)が無効化されます。そうでなければ、終端イテレータのみが無効化されます。

引数
args - 要素のコンストラクタに転送される引数
戻り値
(なし) (1)(c++11以上)
挿入された要素を示す参照 (2)(c++17以上)

 

[環境]

コンパイラ : Visual Studio 2019 pro., Version 16.7.0
OS: Windows10 home, Version 1909

 

[プログラムソース]

#include <iostream>
#include <vector>
#include <string>


struct President
{
    std::string name;
    std::string country;
    int year;

    President(std::string p_name, std::string p_country, int p_year)
        : name(std::move(p_name)), country(std::move(p_country)), year(p_year)
    {
        std::cout << "I am being constructed.\n";
    }

    President(President&& other) noexcept
        : name(std::move(other.name)), country(std::move(other.country)), year(other.year)
    {
        std::cout << "I am being moved.\n";
    }

    President& operator=(const President& other) = default;
};

std::ostream& operator << (std::ostream& os, const President& president)
{
    os << president.name << ", " << president.country << ", " << president.year;
    return os;
}


int main()
{
    std::vector<President> elections;
    std::cout << "emplace_back:\n";
    elections.emplace_back("Nelson Mandela", "South Africa", 1994);

    std::vector<President> reElections;
    std::cout << "\npush_back:\n";
    reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));


    std::cout << "\nElections:" << std::endl;
    for (auto const& president : elections) {
        std::cout << president << std::endl;
    }
    std::cout << "\nRe-Elections:" << std::endl;
    for (auto const& president : reElections) {
        std::cout << president << std::endl;
    }


    std::cout << "\nContents:\n";
    for (President const& president : elections) {
        std::cout << president.name << " was elected president of "
            << president.country << " in " << president.year << ".\n";
    }

    for (President const& president : reElections) {
        std::cout << president.name << " was re-elected president of "
            << president.country << " in " << president.year << ".\n";
    }
}

 

[出力]

emplace_back:
I am being constructed.

push_back:
I am being constructed.
I am being moved.

Elections:
Nelson Mandela, South Africa, 1994

Re-Elections:
Franklin Delano Roosevelt, the USA, 1936

Contents:
Nelson Mandela was elected president of South Africa in 1994.
Franklin Delano Roosevelt was re-elected president of the USA in 1936.

 


4. emplace (c++11)

[概要]

emplace を使った要素を挿入する例を示します。

 

std::vector<T,Allocator>::emplace
template< class... Args >
iterator emplace( const_iterator pos, Args&&... args );
(c++11以上)

新しい要素を pos の前に直接挿入します。
c++11 以降で使用可能です。

引数
pos - 前に新しい要素が構築されるイテレータ
args - 要素のコンストラクタに転送される引数
戻り値
挿入された要素を指すイテレータ。

 

[環境]

コンパイラ : Visual Studio 2019 pro., Version 16.7.0
OS: Windows10 home, Version 1909

 

[プログラムソース]

#include <iostream>
#include <vector>
#include <string>

struct President
{
    std::string name;
    std::string country;
    int year;

    President(std::string p_name, std::string p_country, int p_year)
        : name(std::move(p_name)), country(std::move(p_country)), year(p_year)
    {
        std::cout << "I am being constructed.\n";
    }

    President(President&& other) noexcept
        : name(std::move(other.name)), country(std::move(other.country)), year(other.year)
    {
        std::cout << "I am being moved.\n";
    }

    President& operator=(const President& other) = default;
};

std::ostream& operator << (std::ostream& os, const President& president)
{
    os << president.name << ", " << president.country << ", " << president.year;
    return os;
}


int main()
{
    std::vector<President> elections;
    std::cout << "emplace_back:\n";
    elections.emplace_back("Nelson Mandela", "South Africa", 1994);
    elections.emplace_back("Franklin Delano Roosevelt", "the USA", 1936);
    elections.emplace_back("Foo", "Japan", 2020);

    std::cout << "\nElections:" << std::endl;
    for (auto const& president : elections) {
        std::cout << president << std::endl;
    }

    elections.emplace(elections.begin()+1, "Boo", "Japan", 2021);

    std::cout << "\nElections:" << std::endl;
    for (auto const& president : elections) {
        std::cout << president << std::endl;
    }
}

 [出力]

emplace_back:
I am being constructed.
I am being constructed.
I am being moved.
I am being constructed.
I am being moved.
I am being moved.

Elections:
Nelson Mandela, South Africa, 1994
Franklin Delano Roosevelt, the USA, 1936
Foo, Japan, 2020
I am being constructed.
I am being moved.
I am being moved.
I am being moved.

Elections:
Nelson Mandela, South Africa, 1994
Boo, Japan, 2021
Franklin Delano Roosevelt, the USA, 1936
Foo, Japan, 2020

 

補足:
新しい size() が現在の capacity() より大きいため、vectorの再構築が発生し、コンテナ内アイテムの移動が発生しているようです。
アイテムの挿入が頻繁に発生する場合、reserve()で必要な領域を事前確保しておく、または std::list を使用する、などを検討することでペナルティを減らせる場合があります。

 

 

ライセンス

本ページの情報は、特記無い限り下記 MIT ライセンスで提供されます。

The MIT License (MIT)

Copyright © 2020-2022 Kinoshita Hidetoshi

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

 


参考

 


 

変更履歴

2022-10-10 - ページデザイン更新
2020-08-11 - 新規作成

 

Programming Items トップページ

プライバシーポリシー