質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

3回答

962閲覧

vectorを用いた配列において、配列の要素を空(void)にする方法

xeno555

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2022/11/28 05:52

前提

c++を勉強し始めたものです。
現在、避難に関するプログラムを作っており、避難者の位置をvectorを用いた配列で管理しています。
避難が完了した避難者の配列の要素を空にしたいのですが、vectorのerase()を用いると
その要素ごと削除されてしまい、csv等で避難者の位置を出力した際に値が左詰めで書き込まれてしまいます。

そこで、避難が完了した避難者の要素を空にして、空の値を出力することができれば
どの避難者がいつ避難完了できたかわかりやすくなるため、そのようにプログラムを
変更したいと思っております。

もし配列の要素を空にできない場合は、それに準ずる値を保持させる方法についてや
似たような手法で同様のことができるのであればそちらを教えていただければ幸いです。

よろしくお願いいたします。

実現したいこと

vectorを用いた配列において、要素に空(void)もしくはそれに準ずる値を保持させ
その値をcsvで出力したい

発生している問題・エラーメッセージ

該当のソースコード

試したこと

補足情報(FW/ツールのバージョンなど)

使用ツール:VisualStudio2022 community
言語:c++

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2022/11/28 09:22

> 避難者の位置をvectorを用いた配列で管理しています 「位置」というのが具体的にどんな型なのかわかりませんが, そのデータ値に「正常データとして有効な値の範囲」のようなものがありますか?(→ある場合は,その外側の値を「無効な値」として用いる,とかじゃダメですか?)
SaitoAtsushi

2022/11/29 02:34

https://qiita.com/xeno555/questions/543d7fce006887b54765 Teratail ではマルチポストは推奨されません。 https://teratail.com/help#posted-otherservice Teratail に限らず複数の場所で質問すると別の場所で既に出ている回答と内容がかぶる (しなくてよい調査をすることになる) などが生じて非礼なふるまいであるとみなされることがあります。 マルチポストがただちに違反ということはありませんが、別の場所でも質問している旨やそこへのリンクを貼るのが好ましい作法です。
xeno555

2022/12/01 02:37

プログラムに関して初めて質問させていただいたため、複数のサイトで同一の質問をすることがマナー違反になるとは知りませんでした。 知らなかったとはいえ非礼な行いをしてしまい、回答者の皆様に不快な思いをさせてしまいすみませんでした。
guest

回答3

0

std::optional をvectorの要素にしてはいかがでしょう。

C++

1 2#include <iostream> 3#include <vector> 4#include <string> 5#include <optional> 6 7int main() { 8 std::vector<std::optional<std::string>> v = { "apple", "banana", "cherry" }; 9 v[1].reset(); 10 11 for ( auto& item : v ) { 12 if ( item ) std::cout << *item; 13 else std::cout << "(null)"; 14 std::cout << std::endl; 15 } 16}

投稿2022/11/28 06:02

編集2022/11/28 06:16
episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

xeno555

2022/12/01 02:38

検討してみます。 ありがとうございます。
guest

0

std::optinal という案が既出ですが,

避難が完了した避難者の…

という話を実装するのであれば,「避難完了したやつのデータは「無効」にする」という,何だか回りくどい(?)扱い方をするよりも,「避難完了したか否か」という意味合いのデータを明確に持たせるのが良いのではないかな,という気もします.


また,そもそもの困り事というのが,

csv等で避難者の位置を出力した際に値が左詰めで書き込まれてしまいます。

という事なのであれば,
「vector内でのある瞬間における位置 = csv等での出力位置」という話にしている実装自体がもう何か違う感.
各データの出力位置が重要なのであれば,各データに「csv等で何列目に位置するデータなのか」という(IDみたいな?)データを持たせるとかすればどうでしょうか.

投稿2022/11/29 05:25

fana

総合スコア11658

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2022/11/29 05:33

なんだろう, 実装時のそのvector型データのルールとして 「並び順(位置)がcsvでの位置と一致する」ということに「した」のであれば,erase()とか言い出すことが間違っているのだから,「避難完了した」ような情報を保持すべきと思う. そうじゃないなら,vector内での位置とcsvでの位置との間に勝手に関係性を想定している部分の側が間違っている. この場合,csvでの位置というのは他の何かから解決する必要がある.
guest

0

結論から言えば std::optional を使うのが綺麗な方法です。 ただ、配列に入れることを考えると常に良いとは言えないという部分はあります。


背景を説明します。

void に対応する値は存在しませんvoid は空であることを表す値ではなく値として扱えないという意味を持つ型です。

オブジェクトとはストレージ (普通はメモリのこと) の領域であると定義されています。 オブジェクトはオブジェクトである限り何かは入っている (ときには全くデタラメな内容かもしれませんが) ので全く空っぽということは出来ず、普通は現れない値を入れることでそれが空であるということにするという約束によって空を表現するのが通例です。 広義には番兵の一種とも言えるでしょう。

std::optional は意味のある値を格納できるだけの大きさに加えてそれが意味のある値なのかどうかを区別するためのフラグを付け加えて内部で管理しており、そのフラグのための領域の分だけサイズが大きくなるのは避けられません。

cpp

1// std::optional<int> は int より大きい! 2#include <iostream> 3#include <optional> 4 5int main() { 6 std::cout << sizeof(int) << std::endl; 7 std::cout << sizeof(std::optional<int>) << std::endl; 8}

一個の値ならともかく配列の要素として使うと結果として全体としてのメモリ使用量が多少は大きくなってしまいます。 それが許容可能かどうかは場合によるでしょう。


ですからとれる選択肢としては

  • メモリ使用量的に許容できるので std::optional を使う
  • 現れることがない適当な値を空の意味で使う
  • 位置を表すオブジェクトを適当にラッピングして std::optional っぽく振る舞いつつ余計なメモリ消費しないクラスを自作する

などが考えられます。

基本的には std::optional をお勧めしますけども良いことばかりではなくそれぞれにメリットとデメリットがあるので状況を見極めて選択が必要です。

投稿2022/11/28 09:31

SaitoAtsushi

総合スコア5446

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問