Code Fix

上級

テンプレートの型推論失敗で no matching function になる原因

テンプレート関数の2つの引数に異なる型を渡したときに出るエラーです。同じ型パラメータTを2箇所で使うテンプレートは、呼び出し時にすべての箇所で矛盾なく同じ型が推論できなければコンパイルできません。

エラーメッセージの読み方

main.cpp:7:21: error: no matching function for call to 'add(int, const char [2])'
main.cpp
ファイル名
7
行番号
21
列番号 — この位置でg++が構文解析に失敗しました
no matching function for call to 'add(int, const char [2])'
内容 — 期待していたもの、または受け付けられなかったもの

このエラーが出る典型パターン

パターン1

 1  #include <iostream>
 2  template <typename T>
 3  T add(T a, T b) {
 4      return a + b;
 5  }
 6  int main() {
 7      std::cout << add(3, "5") << std::endl;
                             ^
 8      return 0;
 9  }
main.cpp:7:21: error: no matching function for call to 'add(int, const char [2])'

同じ型パラメータTを2箇所で使うテンプレートは、両方の引数から矛盾なく同じ型が推論できないとコンパイルできません。3はint、"5"はconst char*で型が異なるため推論に失敗します。

直し方: "5" を 5 にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  #include <iostream>
 2  template <typename T>
 3  T maxOf(T a, T b) {
 4      return a > b ? a : b;
 5  }
 6  int main() {
 7      std::cout << maxOf(10, 3.5) << std::endl;
                                ^
 8      return 0;
 9  }
main.cpp:7:23: error: no matching function for call to 'maxOf(int, double)'

テンプレートは呼び出しごとに具体的な型を1つに確定できて初めてコンパイルが通ります。10はint、3.5はdoubleで型が異なるため、コンパイラはTを1つに決められません。

直し方: 3.5 を 3 にします。

この問題を解いてみる →

パターン3

 1  #include <iostream>
 2  template <typename T>
 3  T multiply(T a, T b) {
 4      return a * b;
 5  }
 6  int main() {
 7      std::cout << multiply(4, '2') << std::endl;
                                  ^
 8      return 0;
 9  }
main.cpp:7:26: error: no matching function for call to 'multiply(int, char)'

「テンプレートは何でも受け付けてくれる万能な関数」というのは誤解です。'2'はchar型であり、4のint型とは別の型として扱われるため型推論が失敗します。

直し方: '2' を 2 にします。

この問題を解いてみる →

パターン4

 1  #include <iostream>
 2  template <typename T>
 3  T sub(T a, T b) {
 4      return a - b;
 5  }
 6  int main() {
 7      std::cout << sub(9, "3") << std::endl;
                             ^
 8      return 0;
 9  }
main.cpp:7:21: error: no matching function for call to 'sub(int, const char [2])'

9はint、"3"はconst char*で型が異なるため、Tを1つに決められません。

直し方: "3" を 3 にします。

この問題を解いてみる →

パターン5

 1  #include <iostream>
 2  template <typename T>
 3  T minOf(T a, T b) {
 4      return a < b ? a : b;
 5  }
 6  int main() {
 7      std::cout << minOf(7, 2.5) << std::endl;
                               ^
 8      return 0;
 9  }
main.cpp:7:23: error: no matching function for call to 'minOf(int, double)'

7はint、2.5はdoubleで型が異なるため、テンプレートの型推論に失敗します。

直し方: 2.5 を 2 にします。

この問題を解いてみる →

よくある誤解

「テンプレートは何でも受け付けてくれる万能な関数」というのは誤解です。テンプレートは呼び出しごとに具体的な型を1つに確定できて初めてコンパイルが通ります。引数ごとに異なる型を渡すと、コンパイラはTを1つに決められず型推論に失敗します。

実務での勘所

この種のエラーの直接的な直し方は2つあります。1つは、呼び出し時に山括弧で明示的に型を指定してmax<double>(a, b)のように書き、型推論そのものを行わせずTをdoubleに固定する方法です。もう1つは、呼び出し前に片方の引数を明示的にキャストして両方の型を揃える方法です。テンプレートは「型を自動で合わせてくれる」魔法ではなく、「呼び出し側が矛盾なく1つの型に決められること」を前提にした仕組みだと理解しておくと、エラーへの対処が早くなります。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)