模板参数推导在 MSVC 上失败:bug?

发布于 2024-12-10 03:43:43 字数 490 浏览 0 评论 0 原文

以下内容在 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]。

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

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].

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

没企图 2024-12-17 03:43:43

这肯定是 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 是左值表达式,以便您可以将其放在赋值的左侧。

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

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

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() 的是一个数组,而不是指针。

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.

月亮邮递员 2024-12-17 03:43:43

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

这就是问题所在,它正在退化为 const char *,但随后它尝试将其转换为 const char [8] 作为返回值。

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

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

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

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

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].

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文