2016-04-25 15 views
-3

I次のコードを持っている:コンパイル時のコード生成

template<typename T, typename... args> 
void func(const my_type<T, args...>& set, std::ofstream t_print, std::ofstream args_print) { 
     t_print << set.get_t() << std::endl; 

     if (sizeof...(args) > 0) 
      data << set.get_args() << std::endl; 
    } 
} 

if条件の評価は時間を実行するために延期され、コンパイラは、本体のコードを生成ifの私の質問は、コンパイラがsizeof...(args) == 0の場合にコードを生成せず、テンプレートの特殊化技術を使用しないようにする方法があるかどうかです。現代のC++には回避策がありますか?サイズがゼロの場合ARGS...の大きさは、しかし、0よりも大きい場合

template <typename T, typename ... ARGS> 
std::enable_if_t<(sizeof...(ARGS)>0)> func(...) { ... } 

この場合、funcだけ過負荷セットの一部として表示されます、あなたは:あなたは常にstd::enable_ifを使用することができます

+0

"sizeof ...(args)== 0'の場合にコンパイラがコードを生成しないようにする"(最適化された)バージョンがコードを生成する場合は、ベンダーにバグを報告してください。 –

+0

申し訳ありませんが、デバッグ設定のコードを生成しました。 –

+0

多型ラムダを使用して、ある種のインラインタグディスパッチを実現できます。[example](http://coliru.stacked-crooked.com/a/616a698807b2148f)。 [生成されたコード](https://godbolt.org/g/20EFoS)を見ると、-O0であっても、決して撮られなかった「分岐」は表示されません。私は人間の読者とコンパイラの両方が普通のタグのディスパッチやSFINAEのアプローチで簡単な時間を持っていると想像していますが、 – melak47

答えて

1

あなたのオーバーロードセットから関数が欠落します。しかし、それはあなたが欲しいと思うかもしれません。

+0

ARGSのサイズが0の場合はオーバーロードを追加する必要があります。新しいC++標準でさえも避けることができるかどうかを尋ねています。 T.C.最適化されたバージョンでは、コンパイラはコードのその部分を生成しないとコメントしました。 –

+0

はい、有効なユースケースを処理できるオーバーロードセットを指定する必要があります。または、コンパイル時の最適化に頼る必要があります。どちらも完全に受け入れられ、最適化されたコードを生成するさまざまな方法です。現代のC++はこれを達成するためのより簡単な手段を提供しますが、呼び出された引数に関数定義を使用できるようにする必要性は取り除かれません。 – KyleKnoepfel

1

以降のみパックを持つから構成され、このための実用的な、非難読化トリック、

template<typename T, typename arg, typename... args> 
void func(const my_type<T, arg, args...>& set, std::ofstream t_print, std::ofstream args_print) { 
    t_print << set.get_t() << std::endl; 
    data << set.get_args() << std::endl; 
} 

は、あなたが「最適化」としてこれを行うことを検討している場合、ちょうどすぐに停止しかしあります。また、アセンブリで直接C++とプログラムの使用について心配する必要があります。ああ、まず、インテルの開発者向けマニュアルを読んで、コンパイラのコード生成よりもCPUの方が良いことを知っておく必要があります。

ボトムライン - このレベルでのパフォーマンスは心配しないでください。 「最適化を有効にしない」とは、「ダムコード生成」を意味しません。最適化を無効にしても、半分程度のコンパイラはif(0) ...を発行しません。

関連する問題