Understanding C++ Template Error
#inc开发者_高级运维lude <iostream>
#include <cstring>
#include <string>
template <typename T>
inline T const& max (T const& a, T const& b)
{
return a < b ? b : a;
}
inline char const* max (char const* a, char const* b)
{
return std::strcmp(a,b) < 0 ? b : a;
}
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
return max (max(a,b), c); // error
}
int main ()
{
::max(7, 42, 68); // OK
const char* s1 = "frederic";
const char* s2 = "anica";
const char* s3 = "lucas";
::max(s1, s2, s3); // ERROR
}
Could anybody please tell me why this is an error?
When you say:
max (max(a,b), c)
max(char*,char*)
returns a pointer BY VALUE. You then return a reference to this value. To make this work, you should make all your max() functions return values rather than references, as I think was suggested in an answer to your previous question, or make the char* overload take and return references to pointers.
You're returning a reference to a temporary. The char*
overload of max returns by value, but the 3-arg template returns by reference.
I don't know exactly why you get an error. I only get a warning on my compiler (GCC). I imagine if you posted the error text, though, someone could figure it out.
If you really want to return a reference, then you have to modify the second overload to return a reference too.
char const* const & max (char const* const & a, char const* const & b)
Your example is equivalent to this, maybe you'll see it better this way:
int foo()
{
return 0;
}
int const & bar()
{
return foo(); // Reference to what???
}
When compiling, I get:
maxtest.cpp: In function `const T& max(const T&, const T&, const T&) [with T = const char*]':
maxtest.cpp:29: instantiated from here
maxtest.cpp:19: warning: returning reference to temporary
That would be because you're returning a reference to a temporary (i.e. your object no longer exists by the time the caller of the function can check its value). This is certainly a bug but, since you said error, I suspect it isn't the bug you meant.
Some of the headers in Visual Studio #define min and max. To get around that, put parentheses around min and max:
return (max) ( (max) (a, b), c );
gcc 4.2.1 gives a warning about returning reference to a temporary, so, changing your code to return by value helps.
BTW: I also renamed max
to my_max
, since max
is already defined in <algorithm>
#include <iostream>
#include <cstring>
#include <string>
template <typename T>
inline T const my_max (T const& a, T const& b)
{
return a < b ? b : a;
}
inline char const* my_max (char const* a, char const* b)
{
return std::strcmp(a,b) < 0 ? b : a;
}
template <typename T>
inline T const my_max (T const& a, T const& b, T const& c)
{
return my_max (my_max(a,b), c); // error
}
int main ()
{
std::cout << my_max(7, 42, 68) << "\n"; // OK
const char* s1 = "frederic";
const char* s2 = "anica";
const char* s3 = "lucas";
std::cout << my_max(s1, s2, s3) << "\n"; // NO ERROR
}
gcc -Wall -Wextra file.cpp -o test
gives no warnings or errors, output is:
68
lucas
精彩评论