模板参数演绎在MSVC上失败:bug?

以下错误在VC ++ 8.0编译器中编译时出错(我还没有在最新的Visual Studio编译器上尝试过)。

错误C2440:'return':无法从'const char *'转换为'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");
}

在函数模板里面,看起来字符串是const char (&)[6]

据我所知,当应用<运算符时,数组应该衰减为指针。 那么,这个错误可能是因为可能的错误吗?


这肯定是Microsoft编译器中的一个错误。

这是C和C ++中的一个重大差异。

 e0 ? e1 : e2

在C ++中,一个条件表达式会产生左值, 除非第二部分( '?' )后面'?'至少一个表达式是右值,而在C中,无论如何,条件表达式总是产生右值。 这意味着,以下代码在C ++中完全有效,但在C中是错误的:

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

在C ++中,它不会给出任何错误,正是因为表达式(a<b?a:b)是左值表达式,所以您可以将它放在赋值的左侧。

现在回到原来的问题。 在你的情况下, abchar (&) [6]类型的数组,并且表达式a<b? a : b a<b? a : b应该产生一个左值,因为不需要数组到指针的转换。 但在Microsoft编译器中,似乎有数组到指针的转换。

为了验证它,我们可以这样写:

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;
}

它也不会给出任何错误(在GCC中),这意味着你传递给f()的表达式是一个数组,而不是一个指针。


据我所知,当应用<运算符时,数组应该衰减为指针。

这就是问题所在,它被腐蚀成一个const char *但是它试图将它转换为const char [8]作为返回值。

我不确定标准对此有何评论,但是如果您将其更改为:

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

要么

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

那么模板参数T将是char *而不是char [8]

链接地址: http://www.djcxy.com/p/9783.html

上一篇: Template argument deduction fails on MSVC: bug?

下一篇: Xpath support in my browser?