开发者

Template argument deduction fails on MSVC: bug?

The following fails to compile on VC++8.0 complier with an error (I haven't tried it on the latest visual studio complier yet.)

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 strings are const char (&)[6].开发者_StackOverflow中文版

As far as i know, when < operator is applied, array should be decayed to pointer. So, could this error be because of a possible bug?


It is most certainly a bug in the Microsoft compiler.

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

 e0 ? e1 : e2

In C++, a condtional-expression produces lvalue, unless at least one of the expressions in the second part (after '?') is an rvalue, while in C, a conditional-expression always produces rvalue, no matter what. That means, the following code is perfectly valid in C++ but it is an error in C:

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

In C++, it would not give any error, precisely because the expression(a<b?a:b) is lvalue expression, so as you can put it on the left side of an assignment.

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

To verify it, one 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 either (in GCC), which means the expression which you pass to f() is an array, not a pointer.


As far as i know, when < operator is applied, array should be decayed to pointer.

That's the problem, it is being decayed into a const char * but then it is trying to convert that into const char [8] for the return value.

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

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 char [8].

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜