How can I implement a common minimum?

When I write

T min(T& a,T& b) {return a<b?a:b;} 

and call min(3,4) , this will result in an error.

How can I implement a common minimum?

+4
source share
2 answers

This is because const lvalue ( T& ) references cannot bind to rvalues ​​( 3 and 4 are r values ​​that intuitively imply that they do not have an object identifier).

Try using lvalue references for const instead, which can be associated with rvalues ​​(after all, the min() function should not change the state of its arguments).

Also, don't forget the template<typename T> if you are writing a function template:

 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; } 

For example, consider this small program:

 #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) } 

Here is a living example .


UPDATE:

The above solution allows you to pass values ​​of the same type to min() , otherwise the compiler will not be able to perform type inference (if the first and second arguments are of different types, what should T be?)

 min(3.14, 42); // Huh? What is `T` here, `double` or `int`? 

To force the compiler to use a specific type for T , you can explicitly specify a template argument:

 min<double>(3.14, 42); 

However, this is not a very elegant choice (the user must enter the correct template argument manually each time). Rather, you can let the function template take two parameters of the template type instead of one:

 #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; } 

And use the std::common_type<> property (available since C ++ 11) to figure out the correct type, which will be used as the return type.

Once again, here is a living example .

+12
source

you need to use the template header

 template<typename T> T const& min(T const & a, T const & b) { return a<b?a:b; } 

You can do this for max in the same way:

 template<typename T> T const& max (T const &a, T const& b) { return a<b? b:a; } 

You must make sure that type T supports the <Operator

+1
source

All Articles