ページ 11

[c++]自分自身のインスタンスを定数で持つ

Posted: 2018年5月15日(火) 10:40
by Kobb
構造体にその構造体自身のインスタンスを定数として持たせたいです。
理想としては以下のような使い方をイメージしています。

コード:

//ill-formed code
struct ColorCode {
	int r, g, b;
	static constexpr ColorCode Red = {255, 0, 0};
}

void f() {
	Rect a(...);
	//すべて同じ挙動になってほしい
	a.Draw(ColorCode(255, 0, 0));
	a.Draw({255, 0, 0});
	a.Draw(ColorCode::Red);
}
自分で言ってて何ですが、トピックタイトル通りの実装は無茶だと思うので、こういう場合の自然な実装方法があればご教授いただきたいです

Re: [c++]自分自身のインスタンスを定数で持つ

Posted: 2018年5月15日(火) 12:12
by かずま
staticメンバなら OK だと思います。
ただし、定義は外部で行わないとだめなようです。

コード:

#include <iostream>
using std::cout;

struct ColorCode {
	int r, g, b;
	ColorCode(int r = 0, int g = 0, int b = 0) : r(r), g(g), b(b) { }
	ColorCode(const ColorCode& cc) : r(cc.r), g(cc.g), b(cc.b) { }
	static const ColorCode Red;
};

struct Rect {
	int left, top, right, bottom;
	Rect(int left = 0, int top = 0, int right = 160, int bottom = 120)
		: left(left), top(top), right(right), bottom(bottom) { }
	void Draw(const ColorCode& cc) {
		cout << "(" << cc.r <<", " << cc.g << ", " << cc.b << ")\n";
	}
};

ColorCode const ColorCode::Red = { 255, 0, 0 };

void f() {
	Rect a(0,0, 320, 240);
	a.Draw(ColorCode(255, 0, 0));
	a.Draw({255, 0, 0});
	a.Draw(ColorCode::Red);
}

int main() { f(); }

Re: [c++]自分自身のインスタンスを定数で持つ

Posted: 2018年5月16日(水) 00:16
by tk-xleader
かずまさんの回答に少々の補足をします。constexpr修飾されたstaticメンバ変数はliteral typeでないといけませんが、lireral typeになれるのは完全型に限られます。
クラス型はその定義が終了するまではクラス内では不完全型になってしまうので、クラス自身のインスタンスをstatic constexprにすることはできません。

単なるconstの場合は完全型に限られないため、クラス内に宣言だけ書いておいて、クラス定義の外で定義をする(要するにかずまさんが提示された方法)ことができます。

Re: [c++]自分自身のインスタンスを定数で持つ

Posted: 2018年5月16日(水) 17:29
by ISLe
コンパイル時定数とするため以下のように記述できます。

コード:

struct ColorCode {
	int r, g, b;
	constexpr ColorCode(int r = 0, int g = 0, int b = 0) : r(r), g(g), b(b) { }
	constexpr ColorCode(const ColorCode& cc) : r(cc.r), g(cc.g), b(cc.b) { }
	static const ColorCode Red;
};
constexpr ColorCode ColorCode::Red = {255, 0, 0};