第51回 確認問題(テンプレート)
STEP 8 の総合確認クイズ 10 問。
Q1 関数テンプレートの正しい宣言は?
generic T f(T x);
template T f(T x);
template<class T> T f(T x);
auto f<T>(T x);
template<class T> が正しい構文。
Q2 テンプレートの実装はどこに書く?
.cpp 側
ヘッダ側
どちらでもよい
バイナリ分離
テンプレートは使用側のコンパイル時に実体化されるため、実装もヘッダに書く必要があります。
Q3 テンプレートの実行時コストは?
基本ゼロ(コンパイル時展開)
仮想関数と同程度
関数ポインタ呼び出し分
ハッシュ分
テンプレートはコンパイル時に型ごとの関数が生成されるので、実行時オーバーヘッドは手書き関数と同等。
Q4 Box<int> b{42}; の <int> は?
継承
テンプレート引数(T に int を当てる)
キャスト
配列サイズ
クラステンプレートの型パラメータ T に int を当てはめる指定。
Q5 C++17 の CTAD で std::pair p{1, 2.5}; の型は?
std::pair<int, int>
std::pair<auto, auto>
std::pair<int, double>
コンパイルエラー
コンストラクタ引数から型を推論。整数リテラル→int、浮動小数リテラル→double。
Q6 可変長テンプレートの宣言は?
template<class T[]>
template<class T*>
template<class... Args>
template va_args T
class... Args でパラメータパック。任意個の型を受け取れる。
Q7 C++17 の fold expression (... + args) の役割は?
配列初期化
パックを演算子で畳み込む(a0+a1+a2+...)
関数合成
型の列挙
C++17 の fold expression。再帰展開を書かずにパックを演算子で畳み込めます。
Q8 std::make_unique<T>(args...) が任意引数を受け取れる仕組みは?
オーバーロード
可変長テンプレート + perfect forwarding
マクロ
va_list
variadic template と std::forward の組み合わせで、型情報を保ったまま転送できる。
Q9 テンプレート特殊化の用途として正しいのは?
コンパイル速度向上
特定の型だけ別実装を提供
継承の代替
メモリ削減
ある型のときだけ違う処理をしたい場合(例:bool 特殊化でビットパック)に使う。
Q10 関数テンプレートの型推論と明示指定の違いは?
推論は常に失敗する
明示指定は禁止
引数から推論できるときは省略可、できないときは明示必須
推論と明示指定は別物
引数型から T が決まる場合は省略可能。戻り値だけで T が決まるような場合は明示指定(zero<int>() など)が必要。