タイトルだと意味不明かもしれないですが、以下のコードでやりたいことはわかっていただけるかと思います
侵入型のリスト構造を関数で再現するようなイメージなのですが、お手上げです
よろしくお願いします
同じシグネチャの関数ポインタを返す関数のシグネチャをtypedefしたい
Re: 同じシグネチャの関数ポインタを返す関数のシグネチャをtypedefしたい
少し考えてみましたが、無理かもしれません。
1引数の関数を「引数の型 -> 戻り値の型」と書くことにします。
今作りたい関数(のシグネチャ)は、
作りたい関数 :: int -> 作りたい関数
ですね。
全体の「作りたい関数」を戻り値に代入すると
作りたい関数 :: int -> (int -> 作りたい関数)
もう一度代入すると
作りたい関数 :: int -> (int -> (int -> (int -> 作りたい関数)))
と無限再帰のようになってしまう気がします。
この表現の具体例として、Haskellで例えば「適当な引数を取って自分自身を返す関数」を作ろうとすると、というエラーになってしまいました。
1引数の関数を「引数の型 -> 戻り値の型」と書くことにします。
今作りたい関数(のシグネチャ)は、
作りたい関数 :: int -> 作りたい関数
ですね。
全体の「作りたい関数」を戻り値に代入すると
作りたい関数 :: int -> (int -> 作りたい関数)
もう一度代入すると
作りたい関数 :: int -> (int -> (int -> (int -> 作りたい関数)))
と無限再帰のようになってしまう気がします。
この表現の具体例として、Haskellで例えば「適当な引数を取って自分自身を返す関数」を作ろうとすると、
GHCi, version 7.8.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> let a i = a
<interactive>:2:11:
Occurs check: cannot construct the infinite type: t1 ~ t -> t1
Relevant bindings include
i :: t (bound at <interactive>:2:7)
a :: t -> t1 (bound at <interactive>:2:5)
In the expression: a
In an equation for ‘a’: a i = a
Prelude>
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 同じシグネチャの関数ポインタを返す関数のシグネチャをtypedefしたい
ご回答ありがとうございます
やっぱり無限再帰になりますよね……
関数の中身は書けるのに宣言が書けないのは嫌な気分です
C++11だとauto使って関数の定義は書けるんですけどね
using Handler = auto (*)(int) -> Handler;
のようにシグネチャは定義出来ないはず(Haskellでもthe infinite typeって言ってますしね)
もう暫く待って他になければ適当なタイミングで解決にしておきます
やっぱり無限再帰になりますよね……
関数の中身は書けるのに宣言が書けないのは嫌な気分です
C++11だとauto使って関数の定義は書けるんですけどね
using Handler = auto (*)(int) -> Handler;
のようにシグネチャは定義出来ないはず(Haskellでもthe infinite typeって言ってますしね)
もう暫く待って他になければ適当なタイミングで解決にしておきます
Re: 同じシグネチャの関数ポインタを返す関数のシグネチャをtypedefしたい
既に回答がありますが、C/C++ではおそらく出来ないと思われます。
代案として、関数の返却値を適当に定義しておいてキャストしてしまう方法が考えられます。
例えばあまりきれいではありませんが
ほかにもポインタを直接返すのではなく、構造体を返す手もあります。
代案として、関数の返却値を適当に定義しておいてキャストしてしまう方法が考えられます。
例えばあまりきれいではありませんが
#include <stdio.h>
#include <stdlib.h>
typedef void (*Handler(int))(int);
Handler* func0(int);
Handler* func2(int n)
{
printf("IN func2\n");
if (n <= 0) {
return NULL;
} else {
return (Handler *)func0;
}
}
Handler* func1(int n)
{
printf("IN func1\n");
if (n <= 0) {
return NULL;
} else {
return (Handler *)func2;
}
}
Handler* func0(int n)
{
printf("IN func0\n");
if (n <= 0) {
return NULL;
} else {
return (Handler *)func1;
}
}
int main(void)
{
int count = 10;
Handler *handler = (Handler *)func0;
while (handler != NULL) {
handler = (Handler *)handler(count--);
}
printf("count = %d\n", count);
return 0;
}
#include <stdio.h>
int count = 0;
typedef struct tgHANDLE Handle;
Handle func0(void);
struct tgHANDLE {
struct tgHANDLE (*func)(void);
};
typedef Handle (*Handler)(void);
Handle func2(void)
{
Handle func;
printf("IN func2\n");
if (count > 10) {
func.func = NULL; // NULLを返せば終了
} else {
++count;
func.func = func0; // 次の関数
}
return func;
}
Handle func1(void)
{
Handle func;
printf("IN func1\n");
if (count > 10) {
func.func = NULL; // NULLを返せば終了
} else {
++count;
func.func = func2; // 次の関数
}
return func;
}
Handle func0(void)
{
Handle func;
printf("IN func0\n");
if (count > 10) {
func.func = NULL; // NULLを返せば終了
} else {
++count;
func.func = func1; // 次の関数
}
return func;
}
int main(void)
{
Handler handler;
handler = func0; // 最初の関数のポインタ
while (handler != NULL) {
handler = handler().func;
}
printf("count = %d\n", count);
return 0;
}
Re: 同じシグネチャの関数ポインタを返す関数のシグネチャをtypedefしたい
遅くなりましたが、ご回答ありがとうざいます
わざわざサンプルまで載せていただいて恐縮です
やはり不可能なようなので、ここらで解決にしておきます
ありがとうございました
わざわざサンプルまで載せていただいて恐縮です
やはり不可能なようなので、ここらで解決にしておきます
ありがとうございました