2016-11-01 5 views
2

引数の量に基づいてオブジェクトのインスタンスを選択するマクロを作成しようとしています。マクロは0〜2つの引数をサポートする必要があります。 望ましい結果は、次の3つのいずれかを選択し、任意の場合は0〜2引数を渡している。ここで引数の量に基づいてオブジェクトのインスタンス化を選択するマクロ

MyClass obj(hardcoded_arg); // Choose this one if no arguments passed to a macro 
    MyClass obj(hardcoded_arg,arg1); // This one if a single argument passed 
    MyClass obj(arg1,arg2); // This one if two arguments passed 

は、私はそれを達成しようとしている方法です:

#define TYPE1(...)  MyClass obj(hardcoded_arg); 
    #define TYPE2(arg1)  MyClass obj(hardcoded_arg,arg1); 
    #define TYPE3(arg1,arg2) MyClass obj(arg1,arg2); 

    #define EXPAND(x) x 
    #define GET_TYPE(DUMMY, _1 ,_2, NAME, ...) NAME 
    #define INSTANTIATE(...) EXPAND(GET_TYPE(DUMMY ,##__VA_ARGS__, TYPE3, TYPE2, TYPE1))(__VA_ARGS__) 

    INSTANTIATE() 
    INSTANTIATE(1) 
    INSTANTIATE(1,2) 

私が試しました

#define VA_ARGS(...) , ##__VA_ARGS__ 
    #define INSTANTIATE(...) EXPAND(GET_TYPE(DUMMY VA_ARGS(__VA_ARGS__), TYPE3, TYPE2, TYPE1))(__VA_ARGS__) 

などの定義を使用していますが、この場合も解決しませんでした。 INSTANTIATE(、)のような解決策は不足しています。

アドバイスありがとうございます。

+0

を私はあなたが必要とする理由を理解しませんまったくマクロ。 3つのコンストラクタがそれぞれ0,1または2のパラメータを取るのはなぜですか? – user463035818

+0

hardcoded_argは呼び出し元オブジェクト – user3348108

+0

の "this"ポインタなので、ポインタを明示的に渡さないのはなぜですか?コードを理解しやすくするだろうか? – user463035818

答えて

1

オーバーロードされたファクトリ関数はどうですか? Like

MyClass create() { return MyClass(hardecoded_arg); } 
MyClass create(type2 arg2) { return MyClass(hardcoded_arg, arg2); } 
MyClass create(type1 arg1, type2 arg2) { return MyClass(arg1, arg2); } 

タイプセーフで、プリプロセッサでトリックを実行する必要はありません。

+0

答えてくれてありがとう!コードが実行時間にとって非常に重要であり、その考え方はコードをすばやくすることであると忘れていました。 – user3348108

+0

MyClassインスタンスをコピーすることは禁止されています – user3348108

+2

@ user3348108そして、あなたはこのコピーを測定しました(これはとにかく簡単です(http://en.cppreference.com/w/cpp/language/copy_elision)ケース)はあなたのプログラムにとても有害ですか?それでは運動はいかがですか?そして一般的なヒント:早すぎる最適化をしないでください。まず、プログラムを読みやすく保守してください。次に、プログラムを測定し、ベンチマークし、プロファイルを作成します。ボトルネックが見つかったら(そして* if *)、注意深く調整してください。 –

0

MyClassのコンストラクタはinitializer_listコンストラクタとexplicitも競合しない場合は、移動/コピーコンストラクタを呼び出すことはありません。次の使用可能性があります

MyClass make_MyClass() { return {hardcoded_arg}; } 

template <typename T> 
MyClass make_MyClass(T&& arg) { return {hardcoded_arg, std::forward<T>(arg)}; } 

template <typename T1, typename T2> 
MyClass make_MyClass(T1&& arg1, T2&& arg2) 
{ 
    return {std::forward<T1>(arg1), std::forward<T2>(arg2)}; 
} 

Demo

+0

答えをありがとう、ありがとう質問。私はマクロを修正する方法を尋ねています。状況がそれほど些細なものなら、私は助けはないだろう。あなたの解決策は、 'this'ポインタであるデフォルト引数値とcv-qualifierを表すブール値を扱うことができません。 – user3348108

+0

どの 'this'ポインタについてお話しますか?私はあなたの質問でそれに関連するものは何も見ませんでした(私の答えを可能な限り一致させて更新できるようにする)。 – Jarod42

関連する問題