I'm following an online course (Pluralsight.com) in C++ and struggling with an exercise on templates, in particular passing an actual number (e.g. 3
) to a template which expects (T& t)
.
The code written by the instructor will not compile on my PC - I believe I understand why it will not compile, but want to how it compiled for the instructor (who demos it) and how you should handle this case.
#include "stdafx.h"
#include <iostream>
template <class T>
T myMax(T& t1, T& t2)
{
return t1 < t2 ? t2 : t1;
}
int main()
{
int result = myMax(3, 4);
return result;
}
EDIT: Fixed typo in code (from my experimenting before asking the question). It seems to run in https://ideone.com/1cjJUD so I'm now not sure why it won't compile for me! (Thanks @user4581301)
EDIT2 Post-answer, change name of function to avoid confusion. Should make question clearer to anyone else who stumbles upon the same thing. https://ideone.com/dZffn6
The compiler error is "C2664 'T max<int>(T &,T &)': cannot convert argument 1 from 'int' to 'int &"
This looks to me like it is failing since 3
is an actual number not a reference to a number stored somewhere. Declaring int a=3;
and passing a
to my max function works fine.
- Am I correct about the reason for the compile failure?
- How does the instructors code compiles without error? Has this changed in more recent C++ versions (I believe the class uses C++03)?
- Is it possible to write a template where I can pass either ByRef or ByVal? Would I end up with 4 cases (a, b); (a&, b); (a, b&); (a&, b&) ?
Because you are returning by value, there's no reason for the parameters to be non-
const
. rvalues (including literals and temporary objects) are compatible withconst
references. So that would be a good way to fix it without dealing with all possible combinations:Note that I've renamed the function to avoid ambiguity with
std::max
. Neil mentioned removing theusing namespace std;
in a comment -- while that line does trigger the problem, removing it is not a complete solution.In particular, even without
using namespace std;
, the codestd::complex<double> a, b; auto c = max(a, b);
will still findstd::max
, defeating the whole purpose of making your function a template so it works with any type! This is a consequence of "argument dependent lookup".So using a different name is the best option.