型Tが参照型か判断するメタ関数を作成し
template <class T> struct is_reference { static const bool value = false; }; template <class T> struct is_reference<T&> { static const bool value = true; };
以下のような処理を書くと、参照型の引数を渡しても値型として処理されてしまう
template <class T> void func(T value) { printf("%s\n", is_reference<T>::value ? "参照型" : "値型"); } int main() { int value = 3; func(value); int& ref_value = value; func(ref_value); return 0; }
値型 値型
テンプレート引数を明示化すると、参照型は参照型として正しく処理される
int main() { int value = 3; func<int>(value); int& ref_value = value; func<int&>(ref_value); return 0; }
値型 参照型
こういった処理の場合、テンプレート引数の指定を強制することが以下の方法でできる
template <class T> struct identity { typedef T type; }
template <class T> void func(typename identity<T>::type value) { printf("%s\n", is_reference<T>::value ? "参照型" : "値型"); } int main() { int value = 3; func<int>(value); int& ref_value = value; func<int&>(ref_value); func(value); // エラー!型Tが指定されていません return 0; }
値型 参照型
なお、参照だけではなくconst修飾にも同じ問題がある
template <class T> struct is_const { static const bool value = false; }; template <class T> struct is_const<T const> { static const bool value = true; };
template <class T> void func(T value) { printf("%s\n", is_const<T>::value ? "const" : "not const"); } int main() { int const value = 3; func(value); func<int const>(value); return 0; }
not const const
これも同様にidentityを使用してテンプレート引数を強制することで解決する
【参考サイト】
低学歴無能俸給生活者の日記>< - implicit_castの実装