模板参数推导在 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]。
据我所知,当应用 <
运算符时,数组应该衰减为指针。
那么,这个错误可能是由于可能的错误造成的吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这肯定是 Microsoft 编译器中的一个错误。
这是 C 和 C++ 的一大区别。
在 C++ 中,条件表达式 生成左值,除非第二部分中至少有一个表达式(在
'?' 之后)
)是一个右值,而在 C 语言中,无论如何,条件表达式总是产生右值。这意味着,以下代码在 C++ 中完全有效,但在 C 中却是错误:在 C++ 中,它不会给出任何错误,正是因为表达式
(a 是左值表达式,以便您可以将其放在赋值的左侧。
现在回到原来的问题。在您的情况下,
a
和b
是char (&)[6]
类型的数组,并且表达式a 应该生成一个左值,因为不需要数组到指针的转换。但在微软编译器中,似乎存在数组到指针的转换。
为了验证这一点,可以这样写:
并且它也给出没有错误(在GCC中),这意味着表达式您传递给
f()
的是一个数组,而不是指针。It is most certainly a bug in the Microsoft compiler.
Here is one big difference in C and C++.
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: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
andb
are arrays of typechar (&) [6]
, and the expressiona<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:
And it gives no error either (in GCC), which means the expression which you pass to
f()
is an array, not a pointer.这就是问题所在,它正在退化为
const char *
,但随后它尝试将其转换为const char [8]
作为返回值。我不确定标准对此有何规定,但如果将其更改为:
或
那么模板参数
T
将是char *
而不是char [ 8]
。That's the problem, it is being decayed into a
const char *
but then it is trying to convert that intoconst char [8]
for the return value.I'm not sure what the standard says about this, but if you change it to either:
or
Then the template parameter
T
will bechar *
insteadchar [8]
.