explicit specialization of ‘Race‘ after instantiation ,implicit instantiation first required here。

报错1:
E:\project\qt\Pokemon3\PokemonServer\pokemon.cpp:470: error: specialization of ‘Race::Race() [with int N = 0]’ after instantiation
Race<0>::Race() : PokemonBase(ATK)
^
报错2:
explicit specialization of ‘Race’ after instantiation
implicit instantiation first required here

instantiation 实例化
specialization 特殊化/具体化

错误原因:显示具体化放在实例化之后,这里首先需要隐式实例化

查阅资料后了解到:
显式具体化声明在关键字 template后面包含<>,而显式实例化没有。

源码 pokemon.h
template <int N>
class Race : public PokemonBase
{
public:
    Race();
    virtual ~Race() = default;
    bool attack(Pokemon& attacker, Pokemon& aim, string& msg, int skillIndex = 0) const;
};

源码pokemon.cpp

template <>
Race<0>::Race() : PokemonBase(ATK)
{
    // _raceName = "Charmander";
    _raceName = "小火龙";
    _expCurve[0] = 5;
    for (int i = 1; i < 14; ++i)
    {
        _expCurve[i] = _expCurve[i - 1] + 5 * i;
    }
    _skillName[0] = "撞击";
    _skillName[1] = "火花";
    _skillName[2] = "怒气";
    _skillName[3] = "火球";
    _skillDscp[0] = "普通攻击";
    _skillDscp[1] = "忽略敌人一半防御的攻击";
    _skillDscp[2] = "增加攻击力";
    _skillDscp[3] = "伤害很高的大招";
    _pp[0] = 10;
    _pp[1] = 3;
    _pp[2] = 5;
}

template <>
bool Race<0>::attack(Pokemon& attacker, Pokemon& aim, string& msg, int skillIndex) const
{
    // dbout << attacker.name() << " uses " << attacker.skillName(skillIndex) << "!\n";

    msg += attacker.skillName(skillIndex) + ' ';

    switch (skillIndex)
    {
    case 1: //spark
    {
        if (dodge(attacker.cspeed(), aim.cspeed(), msg))
            return false;

        int dmg = attacker.catk() + attacker.lv() * 2 - aim.cdef() / 2 + f(4);
        // return aim.takeDamage(dmg);
        bool result = aim.takeDamage(dmg);
        msg += to_string(aim.hp()) + " 1 1 1 ";
        for (int i = 0; i < 3; ++i)
        {
            msg += to_string(aim.cpp(i)) + ' ';
        }
        msg += to_string(attacker.hp()) + " 1 1 1 ";
        for (int i = 0; i < 3; ++i)
        {
            msg += to_string(attacker.cpp(i)) + ' ';
        }
        return result;

        break;
    }
    case 2:				 //rage
        msg += "0 "; // can not dodge

        attacker.changeAtk(attacker.atk() / 8);
        msg += to_string(aim.hp()) + " 1 1 1 ";
        for (int i = 0; i < 3; ++i)
        {
            msg += to_string(aim.cpp(i)) + ' ';
        }
        msg += to_string(attacker.hp()) + " 2 1 1 ";
        for (int i = 0; i < 3; ++i)
        {
            msg += to_string(attacker.cpp(i)) + ' ';
        }
        break;
    case 3: //fireball
    {
        if (dodge(attacker.cspeed(), aim.cspeed(), msg))
            return false;

        int dmg = attacker.catk() * 1.5 - aim.cdef() + 8 + f(4 + attacker.lv());
        bool result = aim.takeDamage(dmg);
        msg += to_string(aim.hp()) + " 1 1 1 ";
        for (int i = 0; i < 3; ++i)
        {
            msg += to_string(aim.cpp(i)) + ' ';
        }
        msg += to_string(attacker.hp()) + " 1 1 1 ";
        for (int i = 0; i < 3; ++i)
        {
            msg += to_string(attacker.cpp(i)) + ' ';
        }
        return result;

        break;
    }
    default:
    {
        //普通攻击
        if (dodge(attacker.cspeed(), aim.cspeed(), msg))
            return false;

        int dmg = attacker.catk() - aim.cdef() + f(4);
        bool result = aim.takeDamage(dmg);
        msg += to_string(aim.hp()) + " 1 1 1 ";
        for (int i = 0; i < 3; ++i)
        {
            msg += to_string(aim.cpp(i)) + ' ';
        }
        msg += to_string(attacker.hp()) + " 1 1 1 ";
        for (int i = 0; i < 3; ++i)
        {
            msg += to_string(attacker.cpp(i)) + ' ';
        }
        return result;

        break;
    }
    } //switch
    return false;
}
//共实例化了四个类,不一一例举

调用优先级:普通函数>显式具体化>显式实例化>普通模版

也就是具体化应该在实例化之前,我做的是具体化,之前的实例化在哪?

发现在以上程序前还有这样一段代码:

PokemonBase* Race0 = new Race<0>();
PokemonBase* Race1 = new Race<1>();
PokemonBase* Race2 = new Race<2>();
PokemonBase* Race3 = new Race<3>();

const PokemonBase* Pokemon::races[] = {Race0,Race1,Race2,Race3};

我们可以回到本源上思考,模板类是减少代码量而产生,模板类定义了,真正的类还没有定义,既然没有定义,新建也就无从谈起

解决方案是将后一段代码移植到前一段代码下方,问题解决。

你可能感兴趣的:(公主挥剑斩恶龙)