报错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.cpptemplate <>
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:                 //ragemsg += "0 "; // can not dodgeattacker.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;}} //switchreturn 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};

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

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

explicit specialization of ‘Race‘ after instantiation ,implicit instantiation first required here。相关推荐

  1. 趣谈implicit instantiation of undefined template

    目的 为implicit instantiation of undefined template 类型提供问题思路参考. 我是受到参考博客 这篇博客思路, 说是增加 #include <QObj ...

  2. HLS_error implicit instantiation of undefined template ‘ssdm_int

    error: implicit instantiation of undefined template 'ssdm_int<3072, false>' 问题描述 在编写HLS代码过程中,使 ...

  3. AiBote 2022 新研发的自动化框架,支持 Android 和 Windows 系统。速度非常快

    Ai-Bot 基于流行的 Node.js 和 JavaScript 语言 的一款新自动化框架,支持 Windows 和 Android 自动化. 1.Windows xpath 元素定位算法支持 支持 ...

  4. Unity内IAP支付二次验证/服务器验证————最白话,手把手教你做系列。

    之前的一篇写了Unity支付的IAP支付接入. 后来就出现了一些问题,数据统计的时候出现大量购买订单.但是实际上账户的钱却没有增加.@¥--&¥--*@¥&@初步判定可能存在部分用户通 ...

  5. Makefile教程,很详细的东西,收藏了~长文慎点=。=

    陈皓 概述  -- 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,m ...

  6. 乐观锁和悲观锁的理解及如何实现,乐观锁的实现方式。看完你就明白了!

    文章目录 前言 面试回答话术: 乐观锁的实现方式: CAS缺点: 悲观锁和乐观锁 2.1.悲观锁 2.2.乐观锁 前言 在了解悲观锁和乐观锁之前,我们先了解一下什么是锁,为什么要用到锁? 技术来源于生 ...

  7. mysql并发更新数据,多用户并发修改数据解决方案。

    mysql并发更新数据,多用户并发修改数据解决方案. 在系统中,有一些如余额.资产.积分的数据,是要保证数据一致性的.如,一个人使用两个设备同时进行消费操作,如何保证数据一致性的问题. 我们一起来思考 ...

  8. 禁用GPU版本TensorFlow,切换到CPU版本TensorFlow。

    #禁用gpu版本TensorFlow,因为CUDA号码从0开始,这里直接让CUDA使用-1的GPU,自然就无法使用gpu了. 代码前面加入: import os os.environ["CU ...

  9. C++调用Python文件,TensorFlow和PyTorch构建的深度学习模型,无法使用GPU的情况分析。

    C++调用Python深度学习模型,包含TensorFlow和PyTorch等构造的模型,然后使用GPU出现问题.包含C++调用Python函数,C++加载模型到GPU,GPU内存占用过大,计算完毕内 ...

最新文章

  1. 数据挖掘与数据仓库区别与联系
  2. php函数变成变量,为什么我不能在PHP函数中将函数作为默认变量提供?
  3. fpga驱动rgb液晶屏_正点原子开拓者FPGA开发板资料连载第五十四章基于的数字识别实验...
  4. 【CF913F】Strongly Connected Tournament 概率神题
  5. 身份令牌toKen Vuex + localStorage结合存储
  6. 访问 Neutron 外部网络 - 每天5分钟玩转 OpenStack(143)
  7. 如何有效解决C与C++的相互调用问题
  8. java jdk 8 中文文档
  9. 如何使用spring2.0
  10. 【leetcode-652】寻找重复的子树
  11. matlab 给图片上画框,matlab在图片上画框
  12. 2021年前端会有什么新变化?
  13. 【转载】STM32的全部AltiumDesigner元件库文件
  14. 手机电话本怎么导入另一个手机
  15. Abase2:字节跳动新一代高可用 NoSQL 数据库
  16. DLL 注入的三种方法详解
  17. 云原生CI/CD:Tekton之trigger介绍
  18. 用adSence赚钱三部曲
  19. SQLite查询记录总数
  20. \(^_^)/ MySQL语句

热门文章

  1. 【React Native】react-navigation导航使用方法
  2. DOS、Mac 和 Unix 文件格式+ UltraEdit使用
  3. Sharding-eth
  4. ZKFC服务异常:Parent znode does not exist.
  5. VC解析XML--使用CMarkup类解析XML
  6. 《SQL Server 管理与维护指南》章节目录
  7. GDAL Data Model(转)
  8. GPS小车移动应用程序
  9. iOS UIbutton 点击无反应的几种情况
  10. 深入理解PHP内核(五)函数的内部结构