C++ 使用标准规范对已定义函数的未定义引用

C++ 使用标准规范对已定义函数的未定义引用,c++,templates,g++,C++,Templates,G++,大家好 我需要你的g++技能来理解发生在我身上的事情 尝试链接时,g++告诉我: undefined reference to `bool Script::Call<bool>(asIScriptFunction*, std::string, ...)' bool脚本::调用(asIScriptFunction*,std::string,…)的未定义引用 鉴于该文件中明确定义了该功能: namespace Script { template<typename RET&g

大家好

我需要你的g++技能来理解发生在我身上的事情

尝试链接时,g++告诉我:

undefined reference to `bool Script::Call<bool>(asIScriptFunction*, std::string, ...)'
bool脚本::调用(asIScriptFunction*,std::string,…)的未定义引用
鉴于该文件中明确定义了该功能:

namespace Script
{
  template<typename RET>
  RET Call(asIScriptFunction* function, string fmt, ...)
  {
    asIScriptContext* context = Script::Engine::Get()->CreateContext();
    va_list ap;

    context->Prepare(function);
    va_start(ap, fmt);
    for (unsigned short i = 0 ; fmt[i] ; ++i)
    {
      if (i == 'O')
    context->SetArgObject(i, va_arg(ap, void*));
      else if (i == 'b')
    context->SetArgByte(i, va_arg(ap, int));
      else if (i == 'i')
    context->SetArgDWord(i, va_arg(ap, int));
      else if (i == 'f')
    context->SetArgFloat(i, va_arg(ap, double));
    }
    va_end(ap);
    context->Execute();

    RET to_ret = ScriptCallGetReturn<RET>(context);
    context->Release();
    return (to_ret);
  }
}

namespace Script
{
  template<> bool  Call<bool> (asIScriptFunction*, string fml, ...);
  template<> int   Call<int>  (asIScriptFunction*, string fml, ...);
  template<> float Call<float>(asIScriptFunction*, string fml, ...);
  template<> void* Call<void*>(asIScriptFunction*, string fml, ...);

  template<>
  void Call<void>(asIScriptFunction* function, string fmt, ...)
  {
    asIScriptContext* context = Script::Engine::Get()->CreateContext();
    va_list ap;

    context->Prepare(function);
    va_start(ap, fmt);
    for (unsigned short i = 0 ; fmt[i] ; ++i)
    {
      switch (fmt[i])
      {
    case '0':
      context->SetArgObject(i, va_arg(ap, void*));
      break ;
    case 'b':
      context->SetArgByte(i, va_arg(ap, int));
      break ;
    case 'i':
      context->SetArgDWord(i, va_arg(ap, int));
      break ;
    case 'f':
      context->SetArgFloat(i, va_arg(ap, double));
      break ;
      }
    }
    va_end(ap);
    context->Execute();
    context->Release();
  }
}
名称空间脚本
{
模板
RET调用(asIScriptFunction*函数,字符串fmt,…)
{
asIScriptContext*context=Script::Engine::Get()->CreateContext();
va_列表ap;
上下文->准备(功能);
va_启动(ap、fmt);
for(无符号短i=0;fmt[i];++i)
{
如果(i='O')
context->SetArgObject(i,va_arg(ap,void*);
else如果(i='b')
context->SetArgByte(i,va_arg(ap,int));
else如果(i=='i')
context->SetArgDWord(i,va_arg(ap,int));
else如果(i='f')
context->SetArgFloat(i,va_arg(ap,double));
}
va_端(ap);
上下文->执行();
RET to_RET=ScriptCallGetReturn(上下文);
上下文->释放();
返回(返回);
}
}
名称空间脚本
{
模板bool调用(asIScriptFunction*,字符串fml,…);
模板int调用(asIScriptFunction*,字符串fml,…);
模板浮点调用(asIScriptFunction*,字符串fml,…);
模板void*调用(asIScriptFunction*,字符串fml,…);
模板
无效调用(asIScriptFunction*函数,字符串fmt,…)
{
asIScriptContext*context=Script::Engine::Get()->CreateContext();
va_列表ap;
上下文->准备(功能);
va_启动(ap、fmt);
for(无符号短i=0;fmt[i];++i)
{
开关(fmt[i])
{
案例“0”:
context->SetArgObject(i,va_arg(ap,void*);
打破
案例“b”:
context->SetArgByte(i,va_arg(ap,int));
打破
案例“i”:
context->SetArgDWord(i,va_arg(ap,int));
打破
案例“f”:
context->SetArgFloat(i,va_arg(ap,double));
打破
}
}
va_端(ap);
上下文->执行();
上下文->释放();
}
}
事实上,这些模板应该被编译(它们在使用它们的同一个文件中)。
发生这种情况的原因是什么?可能是因为我使用了stdarg吗?

函数已声明,但没有在那里实现。链接器正在寻找实现。请注意,在您提供的代码中只实现了
Call
,但
Call
不是

要使您的代码正确链接,只需删除声明:

  template<> bool  Call<bool> (asIScriptFunction*, string fml, ...);
  template<> int   Call<int>  (asIScriptFunction*, string fml, ...);
  template<> float Call<float>(asIScriptFunction*, string fml, ...);
  template<> void* Call<void*>(asIScriptFunction*, string fml, ...);
模板bool调用(asIScriptFunction*,字符串fml,…);
模板int调用(asIScriptFunction*,字符串fml,…);
模板浮点调用(asIScriptFunction*,字符串fml,…);
模板void*调用(asIScriptFunction*,字符串fml,…);
模板bool调用(asIScriptFunction*,字符串fml,…)


这不是在做你认为它在做的事情。这是对
template Call
RET
Holy cow的完整模板专门化的声明。我忘了一半的密码-u-。。。这种专门化在这里甚至不相关…@user626921
Call
(以及
Call
Call
)仍然(在未标记的编辑之后)没有定义(实现),只是声明了…这难道不意味着我不能使用模板进行此操作吗?如果我必须实现它,那么我必须对每种类型都这样做,不是吗?这样做的结果是,我做的工作量与没有模板的情况相同。所以,是的。这意味着我不能使用模板。。。如果我实现了它们,它是有效的,但是我必须复制粘贴代码4次。这是令人失望的,我讨厌它,但我必须使用宏。谢谢您的帮助。@user626921-您不必四次剪切和粘贴代码。这是模板的关键点之一。
bool variable_name = Call<bool> (some_script, other_args);