C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[6]: boost::lambda::bindについて


(過去ログ 58 を表示中)

[トピック内 10 記事 (1 - 10 表示)]  << 0 >>

■33320 / inTopicNo.1)  boost::lambda::bindについて
  
□投稿者/ bluebard (3回)-(2009/02/25(Wed) 18:46:57)

分類:[C/C++] 

ネタ元:http://pc11.2ch.net/test/read.cgi/tech/1232367742/

以下の様なクラスがあった時
struct A
{
	virtual void hoge() = 0;
};

struct B : public A
{
	void hoge()
	{
		std::cout << "hoge\n";
	}
};

struct C
{
	void func(A& a)
	{
		a.hoge();
	}
};

以下のmainを実行する
int main()
{
	C c;
	A* b = new B;

	boost::bind(&C::func, c, _1)(*b); // ok

	boost::lambda::bind(&C::func, c, *b); // error 抽象クラスをインスタンス化できません
	boost::lambda::bind(&C::func, boost::ref(c), boost::ref(*b)); // error 抽象クラスをインスタンス化できません
	boost::lambda::bind(&C::func, boost::lambda::var(c), boost::lambda::var(*b)); // error 抽象クラスをインスタンス化できません

	boost::lambda::bind(&C::func, c, boost::lambda::var(boost::ref(*b))); // ok
}

boost::lambda::bind(&C::func, c, boost::lambda::var(boost::ref(*b))); でコンパイルが通る理由を教えてください。
なぜ、これの場合「抽象クラスをインスタンス化できません」のエラーが発生しないのでしょうか?

引用返信 編集キー/
■33332 / inTopicNo.2)  Re[1]: boost::lambda::bindについて
□投稿者/ επιστημη (1782回)-(2009/02/26(Thu) 09:29:39)
επιστημη さんの Web サイト
> boost::lambda::bind(&C::func, c, boost::lambda::var(boost::ref(*b))); でコンパイルが通る理由を教えてください。
> なぜ、これの場合「抽象クラスをインスタンス化できません」のエラーが発生しないのでしょうか?

参照を作ることで抽象クラスのインスタンス生成が行われないんじゃないでしょか。

引用返信 編集キー/
■33337 / inTopicNo.3)  Re[2]: boost::lambda::bindについて
□投稿者/ bluebard (4回)-(2009/02/26(Thu) 10:04:45)
No33332 (επιστημη さん) に返信

> 参照を作ることで抽象クラスのインスタンス生成が行われないんじゃないでしょか。

boost::lambda::bind(&C::func, boost::ref(c), boost::ref(*b));
boost::lambda::bind(&C::func, boost::lambda::var(c), boost::lambda::var(*b));

これらでも参照を作ってると思いますが、なぜこれでは駄目なんでしょうか?

なぜ、var と ref を一緒に使う必要があるのでしょうか?
引用返信 編集キー/
■33338 / inTopicNo.4)  Re[3]: boost::lambda::bindについて
□投稿者/ επιστημη (1785回)-(2009/02/26(Thu) 10:10:21)
επιστημη さんの Web サイト
ごめん、これ以上はboostのコード読まんとわからんです。
ふぉろーよろしく > 読んでるひと

引用返信 編集キー/
■33363 / inTopicNo.5)  Re[4]: boost::lambda::bindについて
□投稿者/ アキラ (164回)-(2009/02/26(Thu) 16:21:05)
アキラ さんの Web サイト
bindのパラメータがCopyConstructibleを要求するからじゃないですか。
refはoperator T&()が呼ばれたときに、内部で持ってる参照を取り出すので

A a = boost::ref(*b);

となったときにはコピーが発生してしまいます。
bindは部分評価のために、パラメータで受け取った
関数オブジェクトの引数をメンバとして持っておくので
そのときに、上記のようなコピーが発生してるんだと思います。
varも同じように参照にしてるみたいですが、2重に参照にすることで
コピー防止になってるんじゃないかと。

引用返信 編集キー/
■33370 / inTopicNo.6)  Re[5]: boost::lambda::bindについて
□投稿者/ アキラ (165回)-(2009/02/26(Thu) 16:41:06)
アキラ さんの Web サイト
あー、でもGCC 4.4に入ってるC++0xのbindとrefだとこれコンパイル通りますね。

bind(&C::func, c, ref(*b)); // OK

バグかなー。

引用返信 編集キー/
■33371 / inTopicNo.7)  Re[5]: boost::lambda::bindについて
□投稿者/ bluebard (5回)-(2009/02/26(Thu) 16:50:10)
No33363 (アキラ さん) に返信
> bindのパラメータがCopyConstructibleを要求するからじゃないですか。
> refはoperator T&()が呼ばれたときに、内部で持ってる参照を取り出すので
>
> A a = boost::ref(*b);
>
> となったときにはコピーが発生してしまいます。

A は抽象クラスなのでインスタンス化できないので
「A a = boost::ref(*b);」はできないです。
「A& a = boost::ref(*b);」ならともかく

なので、bind内部でコピーが発生してるとは思えないです。
(ソースを見たわけじゃないので分からないですけど・・・)
引用返信 編集キー/
■33373 / inTopicNo.8)  Re[6]: boost::lambda::bindについて
□投稿者/ bluebard (6回)-(2009/02/26(Thu) 16:55:22)
No33370 (アキラ さん) に返信
> あー、でもGCC 4.4に入ってるC++0xのbindとrefだとこれコンパイル通りますね。
>
> bind(&C::func, c, ref(*b)); // OK
>
> バグかなー。

boost::bind なら問題ないことも確認済みです。
引用返信 編集キー/
■33385 / inTopicNo.9)  Re[6]: boost::lambda::bindについて
□投稿者/ アキラ (166回)-(2009/02/26(Thu) 18:33:36)
アキラ さんの Web サイト
No33371 (bluebard さん) に返信
> A は抽象クラスなのでインスタンス化できないので

...

> なので、bind内部でコピーが発生してるとは思えないです。
> (ソースを見たわけじゃないので分からないですけど・・・)

いや、Aがインスタンス化されてるからエラーになってるんですよね。
引用返信 編集キー/
■33390 / inTopicNo.10)  Re[7]: boost::lambda::bindについて
□投稿者/ bluebard (7回)-(2009/02/27(Fri) 10:01:43)
No33385 (アキラ さん) に返信

> いや、Aがインスタンス化されてるからエラーになってるんですよね。

はい、そうです。

http://pc11.2ch.net/test/read.cgi/tech/1232367742/194

ってことだそうです。

remove_referenceが原因ってわかっただけでもいいかなと思います。

それ以上は、私には難しいのでこれぐらいで解決とします。

ありがとうございました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -