c++ - 函数模板中的逻辑错误

标签 c++ stl function-templates

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

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.

这是我的代码:

#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;
}

输出:

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

问题:

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

这里为什么返回A?

最佳答案

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

但是你的第二次调用也是错误的:

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

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

调用此重载的正确方法是传递 char s,或者传递 C 风格的字符串:

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

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

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

最后,关于风格的说明。你char*如果您通过转换传入的 char* 来“作弊”一点,特化可以大大缩短。适当的字符串 std::string 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 <>在函数头之前。

关于c++ - 函数模板中的逻辑错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3912828/

相关文章:

c++ - 如何通过使用自定义构造函数而不调用析构函数来创建具有初始大小的 vector ?

带网页的 C++ 输出

c++ - 列表容器上的 std::set_difference

c++ - 按对象属性搜索对象 vector

c++ - 是否可以在调用函数模板时只指定一些模板参数,然后让编译器推导其他参数

c++ - OpenCV UMat 运算符

c++ - 指针运算符可以在 C++ 中重载吗?

c++ - libc++ 中的 `__gnu_cxx::temporary_buffer`?

c++使用带有枚举类和重载转换运算符的模板函数

c++ - constexpr 静态模板函数 : g++ error is a warning on clang