クラスのネストは良くあることですが 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 #endif
10
11 #include <type_traits>
12
13 template<typename T>
14 struct Foo
15 {
16 template<class U>
17 Foo(T,U){}
18 };
19
20 template<class T>
21 struct Bar1
22 {
23 template<class U>
24 struct Bar2
25 {
26 explicit Bar2(T,U,int){}
27 };
28 #if (__cplusplus >= 201703L) && defined(__clang__) && (__clang_major__ > 5)
29 template<class U>
30 Bar2(T,U,int) -> Bar2<U>;
31 #endif
32 };
33
34 int main() {
35 #if __cplusplus >= 201703L
36 Foo foo(100,1.0);
37 #else
38 Foo<int> foo(100,1.0);
39 #endif
40
41 Bar1<int>::Bar2 bar(1,'a',1);
42 static_assert(std::is_same<decltype(bar),Bar1<int>::Bar2<char>>::value,"");
43 return 0;
44 }この中でネストがわかりやすい箇所です。
13 template<typename T>
14 struct Foo
15 {
16 template<class U>
17 Foo(T,U){}
18 };インスタンスを作る際、以下のようにテンプレート引数指定はいらないです。
35 #if __cplusplus >= 201703L 36 Foo foo(100,1.0); 37 #else
このようにネストの型推論もできるっちゃできるんですが GCC と CLANG の実装に誤差があるらしいです。
残りのコードでお見せしたかったのは GCC で以下の構文がエラーではじかれる点です。
28 #if (__cplusplus >= 201703L) && defined(__clang__) && (__clang_major__ > 5) 29 template<class U> 30 Bar2(T,U,int) -> Bar2<U>; 31 #endif
ま GCC でも推論はできてるので、どうでもいいっちゃあどうでも良いですがね…
(´・ω・`)
筆者は標準規格からは程遠いのでヘッダー等を見てあまり気にならなければ、特に深入りはしないスタンスですからね。
この件は GCC が誤っていて CLANG が正しいという意見もあるみたいですね。
Copyright 2017-2018, by Masaki Komatsu