#include "iostream"
#include "string"
using std::cout, std::cin, std::endl, std::string;
template <typename T, typename U>
auto max(T x, U y);
int main(){
cout << max(5, 6.5) << endl;
return 0;
}
template <typename T, typename U>
auto max(T x, U y) {
/**
* @brief this is a template function that returns the maximum of two values
*/
return (x > y) ? x : y;
}
hi guys, i want to know why is this not working?, but if change the return type from auto to one of the template type it works well. i know i can put the function ahead of the main function but. here is the error code which sounds reasonable error: use of 'auto max(T, U) [with T = int; U = double]' before deduction of 'auto'
I forgot that you can't use floats as non-type template arguments.
You can, since C++20:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
template <auto A, auto B>
constexprauto my_min()
{
ifconstexpr (A < B) return A; elsereturn B;
}
int main()
{
auto m1 = my_min<1.0, 2>();
auto m2 = my_min<2.0, 1>();
static_assert(std::is_same_v<decltype(m1), double>);
static_assert(std::is_same_v<decltype(m2), int>);
}
I wonder if it's possible to use template incantations to make max(6.5, 4) return a double,
If you write this
1 2 3 4 5 6
constexprauto my_min(auto a, auto b)
{
ifconstexpr (a < b) return a; elsereturn b;
}
// ...
my_min(6.5, 4);
You will get a compiler error because those parameters a and b aren't constant expressions.
There are tricks to work around this problem. For example, since C++17 this will suffice:
1 2 3 4 5 6
constexprauto my_min(auto a, auto b)
{
ifconstexpr (a() < b()) return a(); elsereturn b();
}
// ...
my_min([]{ return 6.5; }, []{ return 4; }); // returns int
The key here is that each lambda's operator() is a constexpr function. There are other tricks in the same vein, but as far as I know, you always have to write something different than 6.5, even if it's SOME_MACRO(6.5) instead.
Putting code tags on the OP's code, as well as a bit of judicious reformatting, makes it a bit easier to notice what's going on:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
#include "iostream"
template <typename T, typename U>
auto max(T x, U y);
int main( )
{
std::cout << max(5, 6.5) << '\n';
}
template <typename T, typename U>
auto max(T x, U y)
{
return (x > y) ? x : y;
}
Templates are a bit of an odd duck when it comes to declaring and defining a template function. The entire body of the template must be visible to the compiler before the function can be used. A template can't have separate declarations and definitions as if it were a normal non-template function. Visual Studio 2022 has this error for the OP's code.
error C3779: 'max': a function that returns 'auto' cannot be used before it is defined
Rewrite the template so it is declared and defined before it is used in main and *POW!* It works!
1 2 3 4 5 6 7 8 9 10 11 12
#include "iostream"
template <typename T, typename U>
auto max(T x, U y)
{
return (x > y) ? x : y;
}
int main( )
{
std::cout << max(5, 6.5) << '\n';
}
If a template function were to be included in a header file the entire template function would have to be in the header, not possible to be split between a header and a separate source translation unit as can be done with non-template functions.