デフォルト引数の値を動的に変える

デフォルト引数は関数の引数にあらかじめ定義された値を入れておくことで、関数を呼ぶときに明示的に値を入れない場合はその値が使われるようになります。

static void Print(int n = 3 /* デフォルト引数 */)
{
    printf("%d\n", n);
}

// 引数を明示的に指定
Print(5); // => 5
// 引数を明示しないとデフォルト引数の3が引数に渡る
Print(); // => 3


これだけを見るとデフォルト引数の値は固定値を取りそうですが、実は式を取ることができるので値を動的に変えることができます。

例えばデフォルト引数の値を1〜100のランダムな数字にしてみます。

#include <stdlib.h>
#include <time.h>

static int GetNumber()
{
    return rand() % 100 + 1;
}

static void Print(int n = GetNumber())
{
    printf("%d\n", n);
}

srand((unsigned int)time(NULL));
Print(); // => 1〜100までのランダムな数字
Print(); // => 上とは違う値


こうすることでデフォルト引数の取り得る値は1〜100と動的に変わるわけです。

これを応用するといろいろな書き方ができます。

// 三項演算子
static void Print(int n = 0 ? 0 : 3*3) {}
// グローバル変数
int g_n = 0;
static void Print(int n = g_n) {}
static void Print(int n = g_n++) {}
static void Print(int n = g_n = 3) {}
// 関数
static void Printf(int n = printf("abc")) {}
static void Printf(int n = g_n = printf("abc")) {}

さらにカンマで区切ることで複数の式を実行することもできます。

static void Print(int n = (
    g_n = printf("abc\n"),
    g_n+1,
    g_n*g_n)
)
{
    printf("%d\n", n);	
}
Print(); // => 16


使い道は分かりませんが...


※環境は、VC++2010 Express