テンプレートな関数/ファンクタのラッパクラスを考える

zxc
記事: 79
登録日時: 13年前
住所: 日本の背骨(?)あたり

テンプレートな関数/ファンクタのラッパクラスを考える

投稿記事 by zxc » 10年前

 もしかしたらstd::functionで上手いこと簡単にいけるのかもしれない。が、まだよく分かってないし、どっちにしろここで引っかかるのならprivateで持つメンバがstd::function型に変わるだけの予定だから使えないような気がする。
 void型の返り値の関数かoperator()を持つクラス(ファンクタ)を持つクラスを作ろうと考えた。ファンクタの型に依存せず、void operator()()があるなら動いていいんじゃないかと。とりあえずテンプレートにして、関数ポインタもしくはファンクタのコピーか参照/ポインタのどちらかは必要だろう。用途に応じて選べたら良いのかもしれない。

分かったらしいことを書き出すと
  • UsingFuncByPtrクラスとUsingFuncクラスのoperator()が呼ばれると落ちるらしい
  • UsingFuncクラスのprivateメンバがFunc型だと落ちない(参照じゃなく実体のコピーなら良いらしい)
  • UsingFuncクラスのprivateメンバをFunc型にした上で、UsingFuncで実体作ってoperator()呼ぶと落ちない。
  • FunctaRefWrapperのoperator()を呼んでも落ちない
  つまりUsingFuncとFunctaRefWrapperは同じように動かない・・・とりあえずUsingFuncは参照が原因で落ちるみたいだけど、改善方法が・・・
実体で持つようにする・・・?
  下のようなコードでやりたい事が出来ないならば、テンプレートはテンプレート型をマクロで実際の型に置き換えたようなコードを作るようなものだという認識はどうやら間違いらしいということだ。
 以下のコードは試行錯誤中のmain.cppファイル中の一部を切り出して纏めたものなので動かないかもしれない(テストしてない)。

CODE:

#include
#include


class Functa{
	private:
		std::string str;
	public:
		Functa(const std::string& s):str(s){}
		void operator()(){
			std::cout
class UsingFuncByPtr{
	private:
		//Func* f_ptr;//error point?
		typename Func* f_ptr;
	public:
		UsingFuncByPtr( Func f):f_ptr( &(f) ){
			std::cout
class UsingFunc{
	private:
		Func& func;//何とか参照かポインタにしたい。
		
	public:
		UsingFunc( Func f):func(f){
			std::cout call_functa(functa);
	FunctaRefWrapper functa_wrap(functa);
	//call_functa();////die
	cout call_functa2(functa);
	UsingFunc call_functa2ref(functa);

	//cout<<"by UsingFunc :";call_functa2();/////Die
	cout<<"by UsingFunc(ref):";call_functa2ref();
	cout<<"sizeof(call_functa2):"<<sizeof(call_functa2)<<endl;
	cout<<"sizeof(call_functa2ref):"<<sizeof(call_functa2ref)<<endl;

}

アバター
usao
記事: 1889
登録日時: 12年前

Re: テンプレートな関数/ファンクタのラッパクラスを考える

投稿記事 by usao » 10年前

>UsingFuncByPtr( Func f):f_ptr( &(f) )

これだと引数が値渡しになってるから,75行目の
>UsingFuncByPtr call_functa(functa);
という使い方では f_ptrの初期化値は「functa のコピーであるFuncta型一時変数」へのポインタ という感じになるので,
operator()の時点ではその一次変数は存在していないのであり,結果として die なのではないでしょうか.
(UsingFuncの方も同様ですね)

zxc
記事: 79
登録日時: 13年前
住所: 日本の背骨(?)あたり

Re: テンプレートな関数/ファンクタのラッパクラスを考える

投稿記事 by zxc » 10年前

 なるほど。問題点はTemplateでもprivateなメンバ変数の型でもなく、引数が値渡しになっているところですか・・・。
UsingFuncByPtrとUsingFuncの両方のコンストラクタで受け取るオブジェクトをFunc&にしたところ落ちないのでおそらくご指摘のとおりだと思います。ありがとうございます。