私が書くとき
T min(T& a,T& b)
{return a<b?a:b;}
を呼び出すとmin(3,4)
、エラーが発生します。
一般的な最小値を実装するにはどうすればよいですか?
これは、非const
左辺値参照 ( T&
) が右辺値にバインドできないためです (3
および4
右辺値であり、直観的にはオブジェクト ID を持たないことを意味します)。
const
代わりに、右辺値にバインドできる左辺値参照を使用してみてください(結局のところ、min()
関数はその引数の状態を変更することは想定されていません)。
また、関数テンプレートtemplate<typename T>
を作成している場合は、次の部分を忘れないでください。
template<typename T> // <== Don't forget this, if you are writing a template
T min(T const& a, T const& b)
// ^^^^^ ^^^^^
{
return (a < b) ? a : b;
}
たとえば、次の小さなプログラムを考えてみましょう。
#include <iostream>
template<typename T> // <== Don't forget this, if you are writing a template
T min(T const& a, T const& b)
// ^^^^^ ^^^^^
{
return (a < b) ? a : b;
}
int main()
{
int x = 42;
int y = 1729;
std::cout << min(x, y) << std::endl; // Passing lvalues, that would be OK also
// with your original code.
std::cout << min(42, 1729) << std::endl; // Passing rvalues, this would not be OK
// with your original code (non-const
// lvalue references cannot bind to rvalues)
}
これが実際の例です。
アップデート:
上記の解決策では、同じ型の値のみをに渡すことができmin()
ます。それ以外の場合、コンパイラは型推定を実行できません (最初の引数と 2 番目の引数の型が異なる場合はどうすればT
よいでしょうか?):
min(3.14, 42); // Huh? What is `T` here, `double` or `int`?
コンパイラに特定の型を強制的に使用させるにはT
、テンプレート引数を明示的に指定できます。
min<double>(3.14, 42);
ただし、これはあまり洗練された選択ではありません (ユーザーは毎回正しいテンプレート引数を手動で入力する必要があります)。むしろ、関数テンプレートが 1 つではなく2 つのテンプレート型パラメーターを受け入れるようにすることができます。
#include <type_traits>
template<typename T, typename U>
typename std::common_type<T, U>::type min(T const& a, U const& b)
{
return (a < b) ? a : b;
}
また、std::common_type<>
型特性 (C++11 以降で使用可能) を使用して、戻り値の型として使用する適切な型を見つけます。
繰り返しますが、これは実際の例です。
テンプレートヘッダーを使用する必要があります
template<typename T>
T const& min(T const & a, T const & b)
{
return a<b?a:b;
}
同様の方法で max に対してそれを行うことができます:
template<typename T>
T const& max (T const &a, T const& b)
{
return a<b? b:a;
}
タイプ T が < 演算子をサポートしていることを確認する必要があります