milk_spoonのブログ

さじの情報科学的活動、考えたこと、その他を雑記するためのブログです。

【C++】メンバ変数のstd::arrayの宣言時初期化で躓いた

STLちゃんと使ってますかー?
自分は結構std::array使います。
というか基本、C言語の人が生配列使いたいなーって思うところが全部std::arrayに置き換わる感じです。
今日もこんな感じでテーブルをstd::arrayで作って、色々と計算に使ったりしました。
(もちろん、テーブルの大きさは例として小さくしてありますが…)

#include<iostream>
#include<array>

int main()
{
	//配列と同じ形の初期化が使える  //int table[3] = {1, 2, 3};
	const std::array<int, 3> table = { 1, 2, 3 };

	//便利なメンバ関数や、イテレータなどの利用が可能
	for (int i = 0; i < table.size(); ++i)
	{
		std::cout << table[i] << "|";
	}
	std::cout << '\n';

}

コメントにも書いたとおり、生配列の記法+便利(というかCが不自由すぎ)な機能があるのでナイスです。

さて、今日はたくさんテーブルを作って計算してたのですが
その内の一つの処理が少し複雑だったので、std::arrayはクラスに持たせて複雑な処理はそこにまとめ、main内はすっきり書けるようにしたいなあと思いました。
ちゃちゃっとこんな感じで…

#include<iostream>
#include<array>

class Table
{
public:
	Table(){}

	//std::arrayの要素を出力
	void print()
	{
		for (size_t i = 0; i < m_data.size(); ++i)
		{
			std::cout << m_data[i] << "|";
		}
		std::cout << '\n';
	}

private:
	const std::array<int, 3> m_data = { 1, 2, 3 };//コンパイルエラー
};

int main()
{
	Table tbl;

	tbl.print();
}

え?動かない、というかコンパイルが通らないというのが今日の困り事でした。

ちなみにかなりコンパイラとか環境によって違う案件のようなので書いておくと、環境は
Microsoft Visual Studio Express 2013 for Windows Desktop
update 4
って感じです。

色々調べたら思ったよりも沼という感じだったので、結論から言うと下記のコードは動きます。

#include<iostream>
#include<array>

class Table
{
public:
	Table(){}

	void print()
	{
		for (size_t i = 0; i < m_data.size(); ++i)
		{
			std::cout << m_data[i] << "|";
		}
		std::cout << '\n';
	}

private:
    //コンパイルエラー  …(1)
	//const std::array<int, 3> m_data = { 1, 2, 3 };
    //コンパイルエラー  …(2)
	//const std::array<int, 3> m_data = {{ 1, 2, 3 }};
    //コンパイル…は通るが構文エラー表示  …(3)
	//const std::array<int, 3> m_data = std::array < int, 3 > { 1, 2, 3 };
    //OK  …(4)
	const std::array<int, 3> m_data = std::array < int, 3 > {{ 1, 2, 3 }};
};


int main()
{
	Table tbl;

	tbl.print();
}

コメントで色々試してみたりしたものを置いておきました。エラー内容やコンパイルOKかどうかが変わります。

そもそも(1)と(2)のm_data={~}型の初期化は使えません。
(1)か(2)のとき、C2797のコンパイルエラーが出ます。
これについての説明は以下です。
コンパイラ エラー C2797
この書き方が実装されてないみたいです。実装されていないなら仕方がないです。
下の方に記述がありますが、明示的にコンストラクタを呼び出して初期化、という感じで解決するようです。
じゃあ(3)の

const std::array<int, 3> m_data = std::array < int, 3 > { 1, 2, 3 }

で解決、と思いますよね

ところが、さっきの(1)および(3)ではC2797の他にもう一つエラーが出ます。
"IntelliSense: このサブオブジェクト初期化子では中かっこを省略できません"
というものです。
面白いのは(?)このエラーはコンパイルエラーにはならないところです。
(1)はコンパイルエラー、(3)はコンパイルは通り、プログラムが問題なく動くのです。
ということはコンパイルを妨げるのはC2797だけ、ということです。

中括弧が1重だと、中かっこを省略できません~のエラーが出ます。
この中かっこが1重か2重か?ってのが色々面白そうです。
実はC++11の仕様書(参考:N3337)的にはstd::array<N, T>は

std::array<N,T> = {initializer-list};

の形で初期化できるもの、と書いてあるので
(メンバ変数内宣言時の初期化とは言え)1重でエラー出すのはどうなんだ?
と思ったりもしないのですが、集成体(aggregate)の初期化時の中かっこの省略が、メンバ変数の宣言時初期化だとできないようになってるのかな?とか色々思いました。

ってこと考えてると†闇†が深くなってくるので、まあVS2013なら(4)でちゃんと動きます。というのが結論です。
ちなみにg++(GCC) 4.9.2では(2)でちゃんと動きますが、(1)はコンパイルが通りませんでした。
wandbox上でclangも試して見ましたが、(1), (2)のコンパイルは通るものの、-Wallオプション付きだとmain内での中かっこ1重の
初期化、および(1)について、警告が出る状態でした。
三者三様ですね。

コンパイラで色々違いが出たり、初期化子リストやaggregate等、調べたら結構勉強になりました。
詳しい所もまた書きたいと思います。

VirtualBoxに入れたUbuntuが重かったのでxubuntu-desktop入れました

早速1ヶ月空けそうになりました。

 

研究室からVirtualBox上にUbuntu入れてねというお達しがあったので入れました。

VirtualBoxにUbuntu 14.04 LTSをインストールする(準備編) – PC雑記帳

基本はこちら

http://citrras.com/archives/1130

色々設定はこちら(仮想ハードドライブは固定サイズにしたけど!)

Ubuntu VirtualBox その4 - Guest Additionsをインストールする - Ubuntu kledgeb

Guest Additionはこちら、という感じで、

日本語Remix 14.04を入れました。

 

ところがGuest Additionを入れたのにもかかわらず、

Virtualbox上のUbuntu14.04が遅く感じる時: 水より柔弱

こちらも試した・確認したにもかかわらず、重いのでTwitterでつぶやいてみたところ

デスクトップ環境を変えてみてはどうか、と提案をもらいました。

教えてくれた方がXfce4を使っているということ、Xfce4は割と軽いことで有名だそうなので、入れてみることにしました!

 

ところがapt-cache search xfce4とすると、xfce4-なんちゃら、ってパッケージがどんどん出てきちゃうんですね。

f:id:milk_spoon:20150416035237p:plain

 とりあえずxubuntu-desktopというパッケージを入れればXfce4を確実にインストールできるようだ、ということは分かったのでインストールしました!

 

f:id:milk_spoon:20150416040005p:plain

 確かに結構軽いかもしれないです...

ただ、再起動→ログインとかその他もろもろの処理に時間がかかってるのでそもそものスペック不足が感じられて悲しいですが。

 

困ったことが1つ。

もともとのUbuntuのデスクトップ環境の方(ログイン時に切り替え可能)も、なんだかXfce4らいくな見た目になってしまったのです…。

なんと一回直したら状況が再現できないというなかなかファンキーなことになってしまったのでスクリーンショットがないのですが、「左のランチャーはそのままに、背景が青いネズミに、ウィンドウのフレームが白」という状態でした。

 

f:id:milk_spoon:20150416041416p:plain

 (Xubuntu - Wikipedia, the free encyclopedia)

ちょうどこの写真に、ランチャーはUbuntuのデフォルトのような感じでした。

 

Xfce4が軽ければUbuntuデフォルトのは使わないんですが、なんとなく収まりが悪いので直す方法を模索していたところ

f:id:milk_spoon:20150416044018p:plain

デスクトップで右クリ→「背景の変更」

これでテーマをAmbiance, 背景を一番左下にあるものに設定すればOKでした。単純でした…

背景は別のものでいいのですが、ウィンドウの見た目がかなり見辛かったので戻せて良かったです。

 

ちなみに、後から知ったのですが、xubuntu-desktopはXfce4-なんとか(とかその他色々)、を全部色々まとめた感じのパッケージみたいです。

Xfce4-*を調節しつつ入れたほうがカスタマイズできるみたいです、というかそうしていればUbuntuのデザイン変更もなかったのでは…

参考?:http://askubuntu.com/questions/305646/gui-for-ubuntu-server-xfce-or-xubuntu-desktop

情報が古いかなあ…?

まあ万が一自分と同じドツボにはまってる人がいたらお役立てください(?)

3/14「早稲田情報科学ジュニアアカデミー」3/15「☆女子学生がITの未来にふれる一日☆」にTAとして参加しました!

3/14「早稲田情報科学ジュニアアカデミー」無料体験・説明会
3/15「☆女子学生がITの未来にふれる一日☆」
にTAとして参加しました!

f:id:milk_spoon:20150320145126j:plain
3/15 受講者・スタッフ皆でわいわいお昼中

どちらでも、Siv3Dを使ったプログラミングを小〜高校生の方に体験してもらうというカリキュラムがあり、その中で質問を受け付けたり、特定の動作が実現できなくて困っている子のサポートをしたりしました。
短い時間の中でもどんどんSiv3Dでのプログラミングを吸収していく子どもたちを見て、若いっていいなあ…と思ったりもしましたw
難しい部分が書けて喜んでいる子や、ちょっとヒントを出したところからどんどん想像力をふくらませて作品を作っていく子を見ると、プログラミングを教えるのがとっても楽しくなりますね!
私自身も、会場のマイクロソフト品川本社内を見学させていただいたり、他の講演者の方とお話させていただいたり、実り多い時間を過ごすことができたので、とっても嬉しかったですo(^-^)o

はじめに

さじ(@DragonIcecle)の情報科学的活動、考えたこと、その他を雑記するためのブログです。

イベントの記録や、有益(と思われる)情報などの全般的な発信場所として考えています。

特にゲームなどのカテゴリでブログを分けることは今のところ考えていませんが、

記事が累積すれば視野です。

 

プロフィール

HN:さじ(表記ゆれあり)

早稲田大学 基幹理工学部情報理工学科 4年

サークル:早稲田コンピュータエンタテインメント(WCE)、わせポケ

WCEプログラミング班