2012年9月13日木曜日

引数の値を集計してデフォルト引数に反映させる(動的デフォルト引数)

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

動的デフォルト引数で何か面白いことできないかな、と思って作ってみました。

github
ideone

#include <iostream>
#include "arggregate.hpp"

// 集計カテゴリの定義(現状は行ごとにカテゴリ化される。)
typedef ::arggregate::ArggregateCategory(test)  Arggregate1;
typedef ::arggregate::ArggregateCategory(test)  Arggregate2;

typedef ::arggregate::Min<int, ::arggregate::Max<int> > MinMax;

void f1(Arggregate1::Decl< int, ::arggregate::Min<int> >::Type x=Arggregate1::Value< int, ::arggregate::Min<int> >(1000) )
{
    if( x.is_default() ) ::std::cout << x << ::std::endl;
}

void f2(Arggregate2::Decl< int, MinMax >::Type x1=Arggregate2::Value< int, ::arggregate::Min<int> >(-1)
    , Arggregate2::Decl< int, MinMax >::Type x2=Arggregate2::Value< int, ::arggregate::Max<int> >(1000) )
{
    ::std::cout << x1 << ":" << x2 << ::std::endl;
}

int main(void)
{
    {
        ::std::cout << "----- f1 ----- " << ::std::endl;

        f1();   // 集計情報 0 のため 通常デフォルト引数が渡される
        for( int i=10; i > 0; --i )
        {
            f1(i);  // 通常使用
        }
        f1();   // 集計した結果の最小値がデフォルト引数となる
    }
    
    {
        ::std::cout << "----- f2 ----- " << ::std::endl;
        
        f2();   // 集計情報 0 のため 通常デフォルト引数が渡される
        for( int i=10; i > 0; --i )
        {
            f2(i);  // 第一引数のみ指定、第二引数にも集計結果が反映される
        }
        f2();   // 集計した結果の最小、最大値がデフォルト引数となる
    }

    return 0;
}




カテゴリ
typedef ::arggregate::ArggregateCategory(test)  Arggregate1;
カテゴリの定義をします。こちらのカテゴリごとに情報が集計されます。
現時点では、__LINE__ ごとにカテゴリが分けられます。
(※とりあえずの実装です。将来的に変更する予定です。)

引数の型
Arggregate1::Decl< int, ::arggregate::Min<int> >::Type
集計用の引数の型です。

Decl template の1つ目に本来の型を指定します。
2つ目に集計を行うクラスを指定します。
上の例では、Min と Min, Max を組み合わせた MinMax を使用しています。
(※現時点では、Min,Max のみです。今後増やす予定)

デフォルト引数の値
Arggregate1::Value< int, ::arggregate::Min<int> >(1000)
デフォルト引数の値を指定します。

2つ目の template に指定するのは単一の集計クラスです。(Min と Max を同時指定はできない)
Min の場合、今までに渡された値の最小値をデフォルト引数として使用します。

Value 関数の引数には、デフォルトのデフォルト引数の値を指定します。
サンプリングされた値がない場合に、使用されます。


最後に
なんとなく使えそうな気もするが、どういうときに使えばいいかサッパリ。

0 件のコメント:

コメントを投稿