次のメタ関数があるとします。
template <typename T>
struct make_pair {
using type = std::pair<
typename std::remove_reference<T>::type,
typename std::remove_reference<T>::type
>;
};
代わりにこれ(または他の何か)を行うとコンパイル速度が向上しますか?
template <typename T>
struct make_pair {
using without_reference = typename std::remove_reference<T>::type;
using type = std::pair<without_reference, without_reference>;
};
2 つの可能性があります。
コンパイラは、 を見るたびに何らかの作業を行う必要があり
typename std::remove_reference<T>::type
ます。中間エイリアスの使用には、ある種の「キャッシング」動作があり、これにより、コンパイラーは一度だけ何らかの作業を行うことができます。コンパイル時のパフォーマンスは、コンパイラが実行する必要があるテンプレートのインスタンス化の数で測定されます。
std::remove_reference<T>::type
は と同じ型を参照するためstd::remove_reference<T>::type
、どちらの場合も必要なテンプレートのインスタンス化は 1 つだけであるため、どちらの実装も同等の WRT コンパイル時のパフォーマンスになります。
Bが正しいと思いますが、確認したいと思います。答えがコンパイラ固有のものであることが判明した場合、私は主に Clang と GCC の答えを知りたいと思っています。
編集:
テストプログラムのコンパイルをベンチマークして、作業するデータを取得しました。テストプログラムは次のようなことを行います:
template <typename ...> struct result;
template <typename T>
struct with_cache {
using without_reference = typename std::remove_reference<T>::type;
using type = result<without_reference, ..., without_reference>;
};
template <typename T>
struct without_cache {
using type = result<
typename std::remove_reference<T>::type,
...,
typename std::remove_reference<T>::type
>;
{ };
using Result = with[out]_cache<int>::type;
これらは、10,000 個のテンプレート パラメータを使用してプログラムを 10 回コンパイルした平均時間ですresult<>
。
-------------------------
| g++ 4.8 | clang++ 3.2 |
-----------------------------------------
| with cache | 0.1628s | 0.3036s |
-----------------------------------------
| without cache | 0.1573s | 0.3785s |
-----------------------------------------
テスト プログラムは、ここで入手できるスクリプトによって生成されます。