vector<foo>(foo: 自作した構造体)にpush_backをしたい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
keito
記事: 33
登録日時: 8年前

vector<foo>(foo: 自作した構造体)にpush_backをしたい

#1

投稿記事 by keito » 6年前

たびたびお世話になってます。C/C++はまだまだ初心者です。

構造体fooをstd::vector<foo>にpush_backしたいのですが、
「"initializer list"から"const foo&"に変換できません」や
「型 "char *"の値を使用して "char"型の実体を初期化はできません」
とコンパイラに怒られてしまいます…。
どうすればエラーが無くなるのでしょうか?

コード:

#include <vector>

struct foo {
	char ch[3];
	char* pch;
	foo(char* c, char* p) :ch(c), pch(new char[3]{ *p }) {} //Error
	~foo() { delete pch; }
};

int main() {
	std::vector<foo> v;
	char c1[3] = "あ";
	const char* c2 = "い";
	v.push_back({ c1, c2 }); //Error
	v.push_back({ c2, c1 }); //Error
}
Error (active) E0304 no instance of overloaded function "std::vector<_Ty, _Alloc>::push_back [with _Ty=foo, _Alloc=std::allocator<foo>]" matches the argument list
Error C2664 'void std::vector<foo,std::allocator<_Ty>>::push_back(_Ty &&)': cannot convert argument 1 from 'initializer list' to 'const foo &'
Error C2664 'void std::vector<foo,std::allocator<_Ty>>::push_back(_Ty &&)': cannot convert argument 1 from 'initializer list' to 'const foo &'
Error (active) E0144 a value of type "char *" cannot be used to initialize an entity of type "char [3]"
Error (active) E0304 no instance of overloaded function "std::vector<_Ty, _Alloc>::push_back [with _Ty=foo, _Alloc=std::allocator<foo>]" matches the argument list

かずま

Re: vector<foo>(foo: 自作した構造体)にpush_backをしたい

#2

投稿記事 by かずま » 6年前

keito さんが書きました:
6年前
構造体fooをstd::vector<foo>にpush_backしたいのですが、
「"initializer list"から"const foo&"に変換できません」や
「型 "char *"の値を使用して "char"型の実体を初期化はできません」
とコンパイラに怒られてしまいます…。
エラーメッセージを示すときは、行番号も付けてください。

:ch(c), ですが、ch は char[3], c は char * です。
char[3] は、char * では初期化できません。
{ 'a', 'b', '\0' } のような初期化リストなら、char[3] を初期化できます。

pch(new char[3]]{ *p }) では、*p が char であり、その値は
p[0] の 1文字だけです。pch[0] は p[0] で初期化されますが、
pch[1] と pch[2] は 0 に初期化されます。

次に、ポインタをメンバ変数に持つクラスでは、
コピーコンストラクタと代入演算子を定義しないと
おかしなことになります。

push_back() で vector に fooオブジェクトを入れるとき、
コピーコンストラクタが使用されます。
これを定義していないと、ch[0], ch[1], ch[2], pch がコピーされます。
pch[0], pch[1], pch[2] はコピーされません。
pch だけがコピーされると、2つのオブジェクトの pch が同じ領域を指し、
デストラクタで二重に delete されて、問題になります。

また、new[] で確保された領域の解放は、
delete ではなく、delete[] です。
keito さんが書きました:
6年前
どうすればエラーが無くなるのでしょうか?

コード:

#include <iostream>
#include <vector>     // vector
#include <algorithm>  // copy

struct foo {
	char ch[3];
	char *pch;
	foo(const char *c, const char *p) : ch{ c[0], c[1], c[2] },
		pch(new char[3] { p[0], p[1], p[2]}) { }
	foo(const foo& x) : ch{ x.ch[0], x.ch[1], x.ch[2] },
		pch(new char[3] { x.pch[0], x.pch[1], x.pch[2] }) { }
	foo& operator=(const foo& x) {
		if (&x != this) {
			std::copy(x.ch, x.ch + 3, ch);
			std::copy(x.pch, x.pch + 3, pch);
		}
		return *this;
	}
	~foo() { delete[] pch; }
};

int main()
{
	std::vector<foo> v;
	char c1[3] = "ab";
	const char *c2 = "cd";
	v.push_back({ c1, c2 });
	v.push_back({ c2, c1 });
	std::cout << "{ " << v[0].ch << ", " << v[0].pch << " }\n";
	std::cout << "{ " << v[1].ch << ", " << v[1].pch << " }\n";
}

keito
記事: 33
登録日時: 8年前

Re: vector<foo>(foo: 自作した構造体)にpush_backをしたい

#3

投稿記事 by keito » 6年前

ありがとうございます!解決しました!

行番号忘れすみません…
deleteは[]のこと完全に忘れてました……!

返信

“C言語何でも質問掲示板” へ戻る