【C++】关于一个模板函数的编译失败

写个写代码遇到的问题

代码

templateTest.h

struct Ben
{
private:
    int age;
    string name;
public:
    Ben(int age, string name):age(age),name(name){};
    int getAge();
};

struct Kitty
{
private:
    int age;
    string name;
public:
    Kitty(int age, string name):age(age),name(name){};
    int getAge();
    int getAgePlue();
};

非常常规的两个类,但是第二个比第一个多了一个方法。

templateTest.cpp

int Ben::getAge()
{
    return age;
}

int Kitty::getAge()
{
    return age;
}

int Kitty::getAgePlue()
{
    return age + 1;
}

template<typename STUDENT>
int getStudentAge(STUDENT& stu, bool isKitty)
{
    if(isKitty)
    {
        return stu.getAgePlue();
    }
    else return stu.getAge();
}

int main()
{
    auto ben = Ben{22, "Ben"};
    auto kitty = Kitty{22, "Kitty"};

    auto benAge = getStudentAge(ben, false);
    auto kittyAge = getStudentAge(kitty, true);
}

这里写了一个模板方法,根据传入不同的类调用对应类的方法。

这个代码是编译不过的,编译器会提示对 Ben 类找不到 getAgePlue 方法。

templateTest.cpp: In instantiation of 'int getStudentAge(STUDENT&, bool) [with STUDENT = Ben]':
templateTest.cpp:33:48:   required from here
templateTest.cpp:23:20: error: 'struct Ben' has no member named 'getAgePlue'; did you mean 'getAge'?
   23 |         return stu.getAgePlue();
      |                ~~~~^~~~~~~~~~
      |                getAge

分析

如果你像我一样最开始不了解模板方法的原理,你可能有很多种方法解决这个问题。比如这里,其实是传了一个 bool 值进去的,就是 isKitty,在调用的地方也已经特化了。但是不太行。

或者这样?
std::is_same可以判断两个类型是否一致,也是模板方法中针对某个特殊类型进行特殊处理的常用方法。

    if(isKitty and is_same<STUDENT,Kitty>::value)
    {
        return stu.getAgePlue();
    }

我也尝试过在调用的时候,显式声明typename的类型(显式实例化)。

auto kittyAge = getStudentAge<Kitty>(kitty, true);

但是都没什么用,说实话。

模板

C++其实并没有真正意义上的泛型编程。模板并不创建任何函数,而只是告诉编译器如何定义函数。比如这里,需要对Benage的函数时,编译器将按模板模式创建这样的函数,显然,Ben并没有getAgePlue

回到这里,最简单的解决方法就是将模板函数降级成普通函数。或者对模板执行特化。也许还有其他好的解决办法,但我目前能想到的就这两种。

你可能感兴趣的:(c++,开发语言)