函数模板中的逻辑错误

发布于 2024-09-27 05:51:51 字数 1691 浏览 4 评论 0原文

我的教授给了我这个作业。

实现一个名为的通用函数 Max,它接受 3 个泛型参数 输入并返回其中的最大值 3. 为 char* 类型实现专门的函数。

这是我的代码:

#include <iostream>
#include <string>

using namespace std;

template<typename T>
T Max(T first,T second,T third )
{
    if(first > second)
    {
        if(first > third)
        {
            return first;
        }
        else
        {
            return third;
        }
    }
    else if(second > third)
    {
        return second;
    }
    else
    {
        return third;
    }
}


template<>
char* Max(char* first,char* second,char* third)
{   
    if(strcmp(first, second) > 0)
    {
        if(strcmp(first, third) > 0)
        {
            return first;
        }
        else
        {
            return third;
        }
    }
    else if(strcmp(second, third) > 0)
    {
        return second;
    }
    else
    {
        return third;
    }
}

int main(void)
{
    cout << "Greatest in 10, 20, 30 is " << Max(10, 20, 30) << endl;

    char a = 'A';
    char b = 'B';
    char c = 'C';
    char Cptr = *Max(&a, &b, &c);
    cout << "Greatest in A, B ,C is " << Cptr << endl;

    string d = "A";
    string e = "B";
    string f = "C";
    string result = *Max(&d, &e, &f);

    cout << "Greatest in A, B, C is " << result << endl;
}

输出:

10、20、30 中最伟大的是 30
最伟大 A、B、C 中是 C
A、B、C 中最大的是

问题:

如果我在 Max 函数 A、B、C 中传递 char 数据类型,它会返回 C,但如果我传递字符串数据类型 A、B、C,它会返回 A。

为什么这里会返回 A?

My professor has given me this assignment.

Implement a generic function called
Max, which takes 3 arguments of generic
type and returns maximum out of these
3. Implement a specialized function for char* types.

Here's my code :

#include <iostream>
#include <string>

using namespace std;

template<typename T>
T Max(T first,T second,T third )
{
    if(first > second)
    {
        if(first > third)
        {
            return first;
        }
        else
        {
            return third;
        }
    }
    else if(second > third)
    {
        return second;
    }
    else
    {
        return third;
    }
}


template<>
char* Max(char* first,char* second,char* third)
{   
    if(strcmp(first, second) > 0)
    {
        if(strcmp(first, third) > 0)
        {
            return first;
        }
        else
        {
            return third;
        }
    }
    else if(strcmp(second, third) > 0)
    {
        return second;
    }
    else
    {
        return third;
    }
}

int main(void)
{
    cout << "Greatest in 10, 20, 30 is " << Max(10, 20, 30) << endl;

    char a = 'A';
    char b = 'B';
    char c = 'C';
    char Cptr = *Max(&a, &b, &c);
    cout << "Greatest in A, B ,C is " << Cptr << endl;

    string d = "A";
    string e = "B";
    string f = "C";
    string result = *Max(&d, &e, &f);

    cout << "Greatest in A, B, C is " << result << endl;
}

Output :

Greatest in 10, 20, 30 is 30
Greatest
in A, B ,C is C
Greatest in A, B, C is
A

Problem :

If I pass char datatypes in Max function A, B, C, it returns C, but if I pass string datatypes A, B, C it returns A.

Why does it return A here?

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

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

发布评论

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

评论(4

山色无中 2024-10-04 05:51:51

这里有两个问题。其他两个答案已经描述了您第三个电话的问题。

但是您的第二个调用也是错误的:

char a = 'A';
char b = 'B';
char c = 'C';
char Cptr = *Max(&a, &b, &c);

这应该会产生未定义的行为,因为 strcmp 需要以零结尾的字符串,但这不是您输入到函数中的内容。相反,您将其指针传递给各个 char 值,而 strcmp 完全有权对此感到窒息。基本上,任何事情都有可能发生,并且您的代码能否正常工作纯属偶然。

调用此重载的正确方法是传递 char 或传递 C 样式字符串:

char C = Max(a, b, c);

// or:
char as[] = "a";
char bs[] = "b";
char cd[] = "c";
char* result = Max(as, bs, cd);

或者,您可以直接传递字符串文字。

最后,关于风格的说明。如果您通过将传入的 char* 字符串转换为正确的 std::stringchar* 专业化可以大大缩短>s 并重新使用 Max 的通用版本:(

template<>
char* Max(char* first,char* second,char* third)
{
    return Max(string(first), string(second), string(third));
}

当然,这可能效率较低,但在大多数情况下可以安全地忽略它。)

还有另一句话:作业明确要求您专门化char* 的函数模板,所以你的答案是正确的。然而,另一种选择是重载函数而不是专门化它。对于函数模板(与类模板相反),当您不需要更多模板参数时,这是通常的方法:

char* Max(char* first,char* second,char* third)
{
    return Max(string(first), string(second), string(third));
}

请注意,唯一的区别是前面缺少 template <>函数头。

There are two problems here. The other two answers have already described the problem with your third call.

But your second call is also wrong:

char a = 'A';
char b = 'B';
char c = 'C';
char Cptr = *Max(&a, &b, &c);

This should produce undefined behaviour since strcmp expects zero-terminated strings but this isn’t what you feed into the function. Rather, you are passing it pointers to individual char values and strcmp has every right to choke on this. Basically, anything can happen and that your code works is pure chance.

The right way to call this overload would be just to pass chars, or to pass C-style strings:

char C = Max(a, b, c);

// or:
char as[] = "a";
char bs[] = "b";
char cd[] = "c";
char* result = Max(as, bs, cd);

Alternatively, you could pass the string literals directly.

Finally, a note on style. You char* specialization can be shortened considerably if you “cheat” a little bit by converting the incoming char* strings to proper std::strings and re-using the generic version of Max:

template<>
char* Max(char* first,char* second,char* third)
{
    return Max(string(first), string(second), string(third));
}

(Granted, this probably is less efficient but in most cases this can be safely ignored.)

And yet another remark: the assignment explicitly asked you to specialize the function template for char* so your answer is correct. However, an alternative would be to overload the function instead of specializing it. For function templates (as opposed to class templates), this is the usual way when you don’t require more template arguments:

char* Max(char* first,char* second,char* third)
{
    return Max(string(first), string(second), string(third));
}

Note that the only difference is the missing template <> in front of the function header.

不疑不惑不回忆 2024-10-04 05:51:51

在第一种情况下,它使用模板专业化,在第二种情况下,它使用通用模板。

但你的问题是在第二种情况下调用 Max 的方式:

string d = "A";
string e = "B";
string f = "C";
// you're comparing the string addresses here, not their content
string result = *Max(&d, &e, &f); 

应该是:

string d = "A";
string e = "B";
string f = "C";
string result = Max(d, e, f);

另外,我建议在 char* 中使用 const 指针专业化,因为就目前情况而言,除了非常量指针之外,您不能传递任何内容,这并不完全是常见情况。

In the first case, it uses the template specialization, in the second case, the generic template.

But your problem is the way you call Max in the second case:

string d = "A";
string e = "B";
string f = "C";
// you're comparing the string addresses here, not their content
string result = *Max(&d, &e, &f); 

Should be:

string d = "A";
string e = "B";
string f = "C";
string result = Max(d, e, f);

Also, I would suggest using const pointers in the char* specialization because as it stands, you cannot pass anything but non-const pointers which is not exactly the common case.

鯉魚旗 2024-10-04 05:51:51
string result = *Max(&d, &e, &f);

这条线是你的问题。您将指针传递给字符串,因此它实际上返回最高的指针地址。

请记住,堆栈向下增长,因此堆栈的开头具有最高地址。每个后续堆栈分配(即本例中的变量声明)将开始逐渐降低的堆栈地址,因此“A”显示为最大值。

如果你这样写:

string result = Max(d, e, f);

你会得到你期望的答案。

string result = *Max(&d, &e, &f);

This line is your issue. You are passing the pointer to the string in so it is in fact returning the highest pointer address.

Bear in mind that the stack grows downwards so the start of the stack has the highest address. Each subsequent stack allocation (ie variable declaration in this case) will start a progressively lower stack address and hence "A" shows up as the largest value.

If you write this:

string result = Max(d, e, f);

You'll get the answer you expect.

末蓝 2024-10-04 05:51:51

而不是

string result = *Max(*&d, &e, &f)

您需要

string result = Max(d.c_str(), e.c_str(), f.c_str())

注意,如果您的函数采用 const char* 并且不是char*。如果您坚持使用 char*,这是错误的,那么您将不得不放弃常量性

 string result = Max(const_cast<char*>(d.c_str()),

 const_cast<char*>(e.c_str()), const_cast<char*>(f.c_str()));

,但由于您使用的是 string,请注意,您可以简单地将它们与 == < 进行比较。 > ETC。

instead of

string result = *Max(*&d, &e, &f)

you need

string result = Max(d.c_str(), e.c_str(), f.c_str())

Note that this will work if your function takes const char* and not char*. If you insist on using char*, which is wrong, then you'll have to cast away constness

 string result = Max(const_cast<char*>(d.c_str()),

 const_cast<char*>(e.c_str()), const_cast<char*>(f.c_str()));

but since you are using strings, note that you can compare them simply with == < > etc.

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