第322章 関数テンプレートとクラステンプレートの型推論

C++17 で関数テンプレートの型推論はかなり良くなってきたと思います。

特にラムダに関わる部分はテンプレートと auto を組み合わせるべきか個人的に迷うことがありました。

でも最新のアップデートなら、混ぜてもコードが汚染されるような感覚がなくなった気がします(気のせいかも…)。

ではコードを見ながらチェックです。

注記

マクロについては クロスコンパイルのための組み込みマクロ を参照くださいね。

main.cpp. 

  1 #include <iostream>
  2
  3 template<class T>
  4 struct Foo{
  5   Foo(T t){ std::cout << t << '\n'; }
  6 };
  7
  8 template<class T>
  9 auto bar(T t)
 10 {
 11 #if __cplusplus >= 201703L
 12   return Foo(t);
 13 #else
 14   return Foo<T>(t);
 15 #endif
 16 }
 17
 18 int main()
 19 {
 20 #if __cplusplus >= 201703L
 21   bar(100);
 22   [](auto a){
 23     return Foo(a);
 24   }(200);
 25
 26 #else
 27   bar<int>(100);
 28   [](auto a){
 29     return Foo<int>(a);
 30   }(200);
 31
 32 #endif
 33 }

これをビルドして実行すると以下のような出力になります。

$ g++ main.cpp -std=c++17
$ ./a.out
100
200

まず気にしたいのは以下の箇所です。

  3 template<class T>
  4 struct Foo{
  5   Foo(T t){ std::cout << t << '\n'; }
  6 };
  8 template<class T>
  9 auto bar(T t)
 10 {
 12   return Foo(t);

まあ不自然では無いですが Foo はクラステンプレートなので本来ならテンプレート引数を明示的に指定しなきゃだめなはずです。

似たような表現は他にもあります。

 22   [](auto a){
 23     return Foo(a);
 24   }(200);

これはラムダ式内ですが auto から類推されてるので、かなりハードルが高そうですよね。

そうでス。

このようにテンプレート引数の省けるのが新しい推論ってことです。

Copyright 2017-2018, by Masaki Komatsu