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

cpx*_*cpx 7 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");
}
Run Code Online (Sandbox Code Playgroud)

在函数模板中,似乎是字符串const char (&)[6].

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

Naw*_*waz 3

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

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

 e0 ? e1 : e2
Run Code Online (Sandbox Code Playgroud)

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

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

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

现在回到原来的问题。在您的情况下,ab是类型的数组char (&) [6],并且表达式a<b? a : b应该生成左值,因为不需要数组到指针的转换。但在微软编译器中,似乎存在数组到指针的转换。

为了验证这一点,可以这样写:

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;
}
Run Code Online (Sandbox Code Playgroud)

并且它也没有给出错误(在 GCC 中),这意味着您传递给的表达式f()是一个数组,而不是一个指针。