MSVC上的模板参数推断失败:bug?

时间:2011-10-14 21:22:45

标签: c++ templates visual-studio-2005

以下无法在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]

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

2 个答案:

答案 0 :(得分:3)

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

这是C和C ++的一个重大区别。

 e0 ? e1 : e2

在C ++中, condtional-expression 生成 lvalue 除非至少有一个第二部分中的表达式({{1}之后}}是一个右值,而在C中,条件表达式总是产生 rvalue ,无论如何。这意味着,以下代码在C ++中完全有效,但在C:

中是错误的
'?'

在C ++中,它不会给出任何错误,正是因为表达式int a=10, b=20; (a<b?a:b) = 100; //ok in C++, but error in C 是左值表达式,所以你可以将它放在赋值的左侧。

现在回到最初的问题。在您的情况下,(a<b?a:b)ab类型的数组,而表达式char (&) [6]应该生成左值,因为不需要 array-to -pointer 转换。但在Microsoft编译器中,似乎存在 array-to-pointer 转换。

要验证它,可以写下:

a<b? a : b

它也给出no error(在GCC中),这意味着传递给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; } 的表达式是一个数组,而不是一个指针。

答案 1 :(得分:0)

  

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

这就是问题所在,它会被朽烂为const char *但是它会尝试将其转换为const char [8]作为返回值。

我不确定该标准对此有何看法,但如果您将其更改为:

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

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

然后模板参数Tchar *而不是char [8]