C++17 の推論ガイドの構文はあると良い程度で実際はかなり多くの型推論でガイドは不要です。
例えば以下のようなクラステンプレートにガイドは不要です。
1 #if __cplusplus < 201703L
2 # pragma message "cpp version is old! try -std=c++17 "
3 #endif
4
5 #if defined(__GNUC__) && (__GNUC__ < 7)
6 # ifndef __clang__
7 # pragma message "GCCのバージョンが古いです…"
8 # endif
9 #elif not defined(__clang__) && (__clang_major__ > 5)
10 # pragma message "Clangのバージョンが古いです"
11 #endif
12
13 #include <type_traits>
14
15 template<class T>
16 struct A
17 {
18 template<class U>
19 static constexpr bool B = U();
20
21 template<class U,bool V = B<U>>
22 A(T,U){}
23 };
24
25 int main()
26 {
27 #if __cplusplus >= 201703L
28 A a(1,2);
29 static_assert(std::is_same_v<decltype(a),A<int>>);
30 #else
31 A<int> a(1,2);
32 static_assert(std::is_same<decltype(a),A<int>>::value,"");
33 #endif
34 }このコードは static_assert での構文チェックだけをしているので、ビルドしても出力はありません。
クラステンプレート A のコンストラクターの呼び出しで型推論が行われていますね。
15 template<class T>
16 struct A
17 {
18 template<class U>
19 static constexpr bool B = U();
20
21 template<class U,bool V = B<U>>
22 A(T,U){}
23 };このコンストラクターは中々曲者ですが、後述する多重ネストがなければ、あっさり推論をしてくれます。
27 #if __cplusplus >= 201703L 28 A a(1,2); 29 static_assert(std::is_same_v<decltype(a),A<int>>);
とは言え C++17 を使わないのであれば従来の構文が必要となってきます。
30 #else 31 A<int> a(1,2); 32 static_assert(std::is_same<decltype(a),A<int>>::value,""); 33 #endif
テンプレート引数はコード内のドキュメントとしても機能することがあるので、推論なしもありと言えばありですかね。
Copyright 2017-2018, by Masaki Komatsu