電子書籍の厳選無料作品が豊富!

関数ポインタを使用する際に、
指定する先の関数でデフォルト引数が指定されている場合、
関数ポインタを用いて、その引数を省略して呼び出すことはできるのでしょうか?


以下例とします。


void function(int a = 10){};

typedef void (*test)(int a);

test a = &function;

a(); //このように呼び出したい

A 回答 (5件)

ちょっと考えてみましょう。


void function0(int a){};
void function1(int a = 10){};
void function2(int a = 20){};
typedef void (*test)(int);
test f ;
としたときに
f = &function0;
f = &function1;
f = &function2;
いずれも正しいですね。では
f();
としたら、何を引数に渡したらよいでしょう?

void function(int a = 10)
は、あくまで
void function(int a)
であって、
function()
としたときに、プロトタイプから判断して
funtion(10)
としてコンパイルしてくれるだけです。
    • good
    • 0

因みに、Visual C++ (Intel x86)の場合、呼出元が積んだスタック上の引数を開放するのは呼出先の責任(デフォルトはstdcall呼び出し規約)なので、呼ばれた先の関数は「引数が1つ積まれている筈だ」として、積まれていない引数を開放しようとして、スタックの操作を行う筈。



すると、引数がある筈の関数を引数を渡さずに呼んだ場合、呼び出し元に帰って来た時点でスタックがズレて、最悪、暴走します。

なので、functionの定義、test型のタイプ宣言で、呼び出し規約も含めて宣言し、そこだけ「呼出元が積んだスタック上の引数を開放するのは呼出元が行い、呼んだ先では操作しないように」と宣言する必要があります(つまり、functionの定義とtestのプロトタイプにcdecl呼び出し規約が必要)

呼び出し規約を理解しないままやると暴走するから「呼び出し規約って何?」ってレベルの場合は「キャストで無理矢理呼び出す」などという下手な考えはしない事。
    • good
    • 0

因みに



void function(int a = 10){};

typedef void (*test)(void); //testは引数なしで型宣言

test a = (test)(&function); //引数有りを引数無しに無理矢理にキャスト

a(); //引数無しで呼び出す

なら可能。

あと、C言語って、かなり柔軟性が高いから

test a = (test)0x0445E000; //aに0x0445E000をセット
a(); //0445e000番地を無理矢理に呼び出す

とかって事も可能(0445e000番地のメモリにプログラムが無かったら何が起きるか判らない)
    • good
    • 0

>a(); //このように呼び出したい



呼べない。呼ぶとエラーになる。

今のC++やC#の関数定義って「引数の個数や型も含めて定義される」から
void function(int a)

void function(void)
は「異なる定義になり、二重定義にはならない」のです。

事実、ある処理系では
void function(int a)
は、外部参照ラベルが
__void_function_int
としてリンケージエディタに渡され
void function(void)
は、外部参照ラベルが
__void_function_void
としてリンケージエディタに渡され、それぞれが異なる関数として実装されます。

なので

a();

と書くと「そんな関数は知らん」って言われるか「引数の個数が違う」って言われる事になるでしょう。
    • good
    • 0

いいえ.

    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!