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

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

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

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

Q&A

解決済

4回答

20844閲覧

C++ vector配列<構造体>の中のvector配列への代入方法

opyon

総合スコア1009

C++

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

0グッド

2クリップ

投稿2018/11/13 23:14

編集2018/11/15 14:23

###追記2
std::vector::insert

iterator insert(const_iterator position, initializer_list<T> il); // (5) C++11 // 挿入位置と初期化子リストを指定するバージョン { v.insert(v.begin() + 1, {"hhh", "iii"}); }

コメント頂いた@yohhoyさん、@epistemeさん、ありがとうございます。

###追記
boost::range::push_back(target, src);
boost::range::push_back
C++ extend a vector with another vector
@LouiS0616さんのコメントのリンクから検索などしていたら偶然見つけましたのでご参考までに。

###解決!(勘違いでした)
初期化する時にまとめて代入出来ることと勘違いしていました。
結論:直接は出来ない が構造体のメンバ関数などを工夫すれば可能になる

回答くださった方ありがとうございました。

###知りたいこと
下記サンプルコードのようなstd::vector<構造体>の中にあるstd::vector<int>への代入方法が知りたいです。
直感的に書いてみたコードだとエラーとなります。
data[0].vec.push_back({1,2,3});

VSCode上ではvecに赤い波下線でエラーが出ています

ご教示よろしくお願いします。

###試したこと
data[0]::vec.push_back({1,2,3});
これもダメでした。

###エラー

no instance of overloaded function "std::vector<_Tp, _Alloc>::push_back [with _Tp=int, _Alloc=std::allocator<int>]" matches the argument list -- argument types are: ({...}) -- object type is: std::vector<int, std::allocator<int>> std::vector<int> Data::vec

###サンプルコード

C++

1#include <bits/stdc++.h> 2 3struct Data 4{ 5 int id; 6 std::vector<int> vec; 7}; 8 9int main() 10{ 11 std::vector<Data> data(10); 12 13 data[0].id = 1; 14 15//追記2 16//コメントより 17//既存vectorへの要素追加なら 18 data[0].vec.insert(data[0].vec.end(), {4,5,6}); //とも書けます。 19 20 21 //※書き方が分からずここにエラーが出たままです 22 data[0].vec.push_back({1,2,3}); 23 24 //こうすると当然問題無い 25 data[0].vec.push_back(1); 26 data[0].vec.push_back(2); 27 data[0].vec.push_back(3); 28 29 getchar(); 30 return 0; 31}

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

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

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

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

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

guest

回答4

0

C++

1#include <iostream> 2#include <vector> 3 4struct Data 5{ 6 int id; 7 std::vector<int> vec; 8}; 9 10int main() 11{ 12 std::vector<Data> data(10); 13 14 data[0].id = 1; 15 16 // 追加じゃなく、代入なら... 17 data[0].vec.assign({1,2,3}); 18 19 // できたかな? 20 for ( int item : data[0].vec ) { 21 std::cout << item << std::endl; 22 } 23 24 return 0; 25}

投稿2018/11/14 21:19

episteme

総合スコア16614

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

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

opyon

2018/11/14 21:28

回答ありがとうございます。 ループで毎回追加したい時ではなく初回限定なら使えますね。 assign()はあちこちで共通して使いたい配列がある時など外出し変数にして使いますね。
yohhoy

2018/11/15 12:55

既存vectorへの要素追加なら data[0].vec.insert(data[0].vec.end(), {4,5,6}); とも書けます。
opyon

2018/11/15 14:13

コメントありがとうございます。 vectorにもあったのですね。 上記リンク先で確認しました。 // 挿入位置と初期化子リストを指定するバージョン { v.insert(v.begin() + 1, {"hhh", "iii"}); }
guest

0

こんなこともできるのかー程度の話と思って欲しいのですが、Boost.Assign的な方法もあります。
operator,(カンマ演算子)をオーバーロードして要素追加を簡潔にします。

cpp

1#include <bits/stdc++.h> 2 3struct Data 4{ 5 int id; 6 std::vector<int> vec; 7}; 8 9template < class Container > 10class AssignProxy{ 11 Container& container; 12public: 13 AssignProxy(Container& container): container(container) {} 14 15 auto& operator,(typename Container::value_type const& val) { 16 container.emplace_back(val); 17 return *this; 18 } 19}; 20 21auto operator+=(std::vector<int>& vec, int val) { 22 return AssignProxy{vec}, val; 23} 24 25int main() 26{ 27 std::vector<Data> data(10); 28 29 data[0].vec += 1, 2, 3; 30 // ^~~~~~~~~~~ 31 for(auto elem: data[0].vec) { 32 std::cout << elem << " "; 33 } 34 return 0; 35}

Wandboxで実行する

投稿2018/11/14 09:38

mitama_rs

総合スコア165

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

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

opyon

2018/11/14 12:00

回答ありがとうございます。 そんなことまで出来てしまうのですね驚きです。
guest

0

initializer_listを受け取るメンバ関数を用意してやれば良いかと。

C++

1#include <initializer_list> 2#include <iostream> 3#include <vector> 4 5class Data { 6private: 7 int id_; 8 std::vector<int> vec_; 9 10public: 11 Data(int id, const std::initializer_list<int>& lst) 12 : id_(id), vec_(lst) { 13 } 14 friend std::ostream& operator<<(std::ostream&, const Data&); 15}; 16 17std::ostream& operator<<(std::ostream& out, const Data& data) { 18 out << data.id_ << " {"; 19 for(auto elem: data.vec_) { 20 out << elem << ", "; 21 } 22 out << "}"; 23 24 return out; 25} 26 27int main() { 28 Data data{42, {1, 2, 3}}; 29 std::cout << data << "\n"; 30}

実行結果 Wandbox

42 {1, 2, 3, }

投稿2018/11/14 03:00

LouiS0616

総合スコア35658

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

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

opyon

2018/11/14 04:19

回答ありがとうございます。 勘違いの質問ですみませんでした。 みなさんの回答のレベルが高すぎて驚いています。 少しでも参考になるようにじっくり観察したいと思います。 (使いこなせそうにないので眺めるだけ^^;)
opyon

2018/11/15 03:08

情報ありがとうございます。 確かにpython風に使えたら便利ですね。 最近ようやく慣れてきていたのですがこの質問は本当に早とちりの勘違いです^^; 単純に変数宣言時の初期化と混同していました。 みなさんからのレベルの高い回答を頂いて恐縮しております。 すぐに使える技量は無いのですが色々な使い方がありとても参考になります。
opyon

2018/11/15 03:27 編集

boost::push_back(a, b);  イメージにピッタリなのはこれですね。 boostではなくSTLに実装されたら完璧です。 先程のコメントのリンクの中からキーワードで検索してみたところ、こういうのがあるらしいです。 boost::range::push_back(target, src); https://greek0.net/boost-range/boost-range-push_back.html
LouiS0616

2018/11/15 03:42

boostに実装されているのだったら、C++標準でも採用されるチャンスがありそうですね。 いつになるかはわかりませんが。
opyon

2018/11/15 14:20

追記のとおりinsertで実現可能だったようですが、これはこれであると直感的ですよね。
guest

0

ベストアンサー

c++

1data[0].vec.push_back({1,2,3});

push_backの使用方法を間違えています。
要素は一つずつ入れてやらなければなりません。

c++

1data[0].vec.push_back(1); 2data[0].vec.push_back(2); 3data[0].vec.push_back(3);

vecはvecter<int>型であるので、push_backの引数はint型である必要がある。
一方で{1,2,3}と配列を代入しようとしているため、型が違う、と怒られている状態です。


もうクローズしてしまいましたが、まだできないと断じるのは早いかと思います。

素のvectorは静的配列{...}の初期化子、代入演算子を持っています。
これと同じことを、構造体のコンストラクタなり代入演算子なりに宣言することで、一気に代入も可能なのではないかと思っています。

C++

1struct Data 2{ 3 int id; 4 std::vector<int> vec; 5 6 Data(int i, const int v[]) : id(i), vec(v) {}; 7};

ただし、上記では const int * を受け取るコンストラクタが無いよ、とエラーになります。
どうやるのが正しいかな、むむむ。


C++11以上に限りますが、std::begin, std::endを使う方法が一番お望みのものに近いかも知れません。

C++

1#include <vector> 2#include <iterator> 3 4struct Data 5{ 6 int id; 7 std::vector<int> vec; 8 9 Data(int i, int *b, int *e) : id(i), vec(b, e) {}; 10}; 11 12int main(void) 13{ 14 int static_array[] = {1,2,3}; 15 struct Data d(1, std::begin(static_array), std::end(static_array)); 16 17 std::cout << d.vec[2] << std::endl; 18 return 0; 19}

一旦変数に代入しなければいけないのもイマイチですが、これくらいが限界かなと。

また、コンストラクタを経由する必要があります。
代入演算子では引数が1つしか取れない一方、vectorにはbeginとendの2つを渡す必要があるため。

投稿2018/11/13 23:26

編集2018/11/14 03:14
kazto

総合スコア7196

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

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

opyon

2018/11/13 23:28

コメントありがとうございます。 質問編集と被りましたね^^; この方法は分かるのですが、初期化時に出来るような使い方ってありませんでしたっけ?
opyon

2018/11/13 23:37

出来ないことをやろうとしていたわけですね^^; vector初期化時にまとめて代入出来ることと勘違いしてたみたいです。
opyon

2018/11/14 04:16

追記ありがとうございます。 実現可能かもしれませんが、素直に1つづつ入れることにしました。 力不足で回答頂いた内容を理解するのはまだ難しいようです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問