Error outputting a template in MSVC: error?

Below it is not possible to compile VC ++ 8.0 with an error (I have not tried it at the latest visual studio).

error C2440: 'return': cannot convert from 'const char *' to 'const char (&) [6]'

template <typename T> inline T const& compare (T const& a, T const& b) { return a < b ? b : a; } int main() { ::compare("string1", "string2"); } 

Inside the function template, it seems that the string is const char (&)[6] .

As far as I know, when the < operator is used, the array should be decomposed into a pointer. So, can this error occur due to a possible error?

+7
source share
2 answers

This is definitely a bug in the Microsoft compiler.

Here is one big difference in C and C ++.

  e0 ? e1 : e2 

In C ++, the condtional expression expresses an lvalue, if at least one of the expressions in the second part (after '?' ) Is an rvalue, and in C, a conditional expression always produces an rvalue, no matter what. This means the following code is great for C ++, but this is a bug in C:

 int a=10, b=20; (a<b?a:b) = 100; //ok in C++, but error in C 

In C ++, this will not give any error, precisely because the expression (a<b?a:b) is an lvalue expression, since you can put it on the left side of the job.

Now back to the original question. In your case, a and b are arrays of type char (&) [6] , and the expression a<b? a : b a<b? a : b should generate an lvalue, since there is no need to convert the array to a pointer. But in the Microsoft compiler it seems like converting an array to a pointer.

To test this, you can write this:

 template <typename T, int N> inline void f(T const (&a)[N]) {} template <typename T> inline T const& compare (T const& a, T const& b) { f(a < b ? b : a); //is the argument `char*` OR `char (&)[6]`? return a < b ? b : a; } 

And it gives no error (in GCC), which means that the expression you pass to f() is an array, not a pointer.

+3
source

As far as I know, when the < operator is used, the array should be decomposed into a pointer.

In this problem, it splits into const char * , but then tries to convert it to const char [8] for the return value.

I'm not sure what the standard says about this, but if you change it to:

 compare<char *>("string1","string2"); 

or

 compare(static_cast<const char *>("string1"),static_const<const char *>("string2")); 

Then the template parameter T will be char * instead of char [8] .

0
source

All Articles