实例化 C++模板函数

发布于 2024-09-06 17:37:58 字数 892 浏览 12 评论 0原文

我面临一些“未定义引用”错误的问题。我可能无法发布代码,但声明和我调用函数的方式如下:

声明:

template <typename T>
int pitch_detect(deque<T>& x, int offset, int len);

template <typename T>
int is_voiced(
  deque<T>& x, int offset, int len,
  double avg_energy, int pre_voice,
  short& s_flag,
  long nsamples
);

我按如下方式调用上述函数:

x = is_voiced(superFrame_, cur_offset_, f_len_,
    avgEnergy_, frame_voicing_[1], silence_flag_, nsamples_);

y = pitch_detect(superFrame_, cur_offset_, f_len_);

上述语句(我调用函数的位置)被标记作为错误。这些是消息:

对 `int 的未定义引用 is_voiced(std::deque >&, int, int, 双精度型、整数型、短型和长型)

对 `int 的未定义引用 itch_Detect(std::deque >&, int, int)'

非常欢迎解码上述错误的任何帮助。 谢谢, 斯里拉姆

编辑: 上述函数定义在单独的头文件和相应的 C++ 文件中。当我尝试编译它们并创建目标文件时,我没有遇到任何问题。这些错误出现在链接器阶段。

I am facing a few problems with "undefined reference to " errors. I may not be able to post the code, but the declarations and the way I am calling the functions are as follows:

Declarations:

template <typename T>
int pitch_detect(deque<T>& x, int offset, int len);

template <typename T>
int is_voiced(
  deque<T>& x, int offset, int len,
  double avg_energy, int pre_voice,
  short& s_flag,
  long nsamples
);

I am calling the above functions as follows:

x = is_voiced(superFrame_, cur_offset_, f_len_,
    avgEnergy_, frame_voicing_[1], silence_flag_, nsamples_);

y = pitch_detect(superFrame_, cur_offset_, f_len_);

The above statements (where I am calling the functions), get flagged as errors. These are the messages:

undefined reference to `int
is_voiced(std::deque >&, int, int,
double, int, short&, long)

undefined reference to `int
pitch_detect(std::deque >&, int, int)'

Any help in decoding the above errors is most welcome.
Thanks,
Sriram

Edit:
The above functions are defined in a separate header and corresponding C++ file. I get no problems when I try to compile them and create an object file. These errors are seen in the linker stage.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

染年凉城似染瑾 2024-09-13 17:37:58

您是否提供了这些模板的定义?您是自己显式实例化模板还是允许编译器实例化它们?

如果您提供模板声明,但编译器在同一翻译单元中看不到定义,它将假定该模板将在另一个翻译单元中实例化,并且只会生成调用,但不会编译(看不到定义)不可能做到)具体实例化。稍后在链接时,链接器将看到该调用,但不会看到实例化,并且会因未定义引用错误而失败。

最简单的解决方案是将模板声明和定义放在一起:

template <typename T>
int is_voiced( deque<T>& x, int offset, int len, double avg_energy, int pre_voice, short& s_flag, long nsamples ) 
{
  // code here
}

然后,当您使用 is_voiced(...) 时,编译器将隐式为您实例化模板(它会看到代码,并会编译它) )。

在某些情况下,您不希望编译器隐式实例化您的模板(您知道将使用什么类型,并且您不希望编译器允许其他用途——或者编译成本很高并且想要仅通过在单个翻译单元中实例化模板来加快编译速度)。对于这些情况,您将需要在翻译单元中提供您自己的显式实例化。

// header
template <typename T>
int is_voiced( deque<T>& x, int offset, int len, double avg_energy, int pre_voice, short& s_flag, long nsamples ); 

// cpp
template <typename T>
int is_voiced( deque<T>& x, int offset, int len, double avg_energy, int pre_voice, short& s_flag, long nsamples ) {
   // code goes here
}
// explicit instantiation for int
template int is_voiced( deque<int>& x, int offset, int len, double avg_energy, int pre_voice, short& s_flag, long nsamples );

然后编译该实现文件并将其与项目的其余部分链接。

注意:建议在标头中提供完整的模板定义,以便编译器可以隐式实例化它,除非您有充分的理由不这样做。

Have you provided definitions for those templates? Are you explicitly instantiating the templates yourself or allowing the compiler to instantiate them?

If you provide a template declaration but the compiler does not see the definition in the same translation unit, it will assume that the template will be instantiated in another translation unit, and will just generate the call, but not compile (without seeing the definition it cannot possibly do it) the specific instantiation. Later at link time the linker will see the call, but will not see the instantiation and will fail with the undefined reference error.

The simplest solution is just having the template declaration and definition together:

template <typename T>
int is_voiced( deque<T>& x, int offset, int len, double avg_energy, int pre_voice, short& s_flag, long nsamples ) 
{
  // code here
}

Then when you use is_voiced(...) the compiler will implicitly instantiate the template for you (it sees the code, and it will compile it).

There are a few cases where you do not want the compiler to implicitly instantiate your templates (you know what types are going to be used, and you do not want the compiler to allow other uses --or it is expensive to compile and want to speed compilation up by only instantiating the templates in a single translation unit). For those cases you will need to provide your own explicit instantiation in a translation unit.

// header
template <typename T>
int is_voiced( deque<T>& x, int offset, int len, double avg_energy, int pre_voice, short& s_flag, long nsamples ); 

// cpp
template <typename T>
int is_voiced( deque<T>& x, int offset, int len, double avg_energy, int pre_voice, short& s_flag, long nsamples ) {
   // code goes here
}
// explicit instantiation for int
template int is_voiced( deque<int>& x, int offset, int len, double avg_energy, int pre_voice, short& s_flag, long nsamples );

Then compile that implementation file and link it with the rest of the project.

Note: it is advisable to provide the full template definition in the header so that the compiler can implicitly instantiate it, unless you have a good reason not to do so.

﹉夏雨初晴づ 2024-09-13 17:37:58

将函数的定义放在头文件中,而不是放在单独的 CPP 文件中;并且,在头文件中,在函数定义前面添加 inline 关键字,以避免链接器抱怨重复的定义。

Put the definitions of the functions in the header file, instead of in a separate CPP file; and, in the header file, prefix the function definitions with the inline keyword, to avoid the linker complaining about duplicate definitions.

挽你眉间 2024-09-13 17:37:58

我没有尝试过 g++,但是你尝试过显式命名类型吗?

x = is_voiced<PutTypeNameHere>(superFrame_, etc);

定义和调用是从同一个 dll/exe 完成的吗?如果没有,您可能需要使用调用模板函数的类型显式实例化它们。

I haven't tried g++, but have you tried explicitly naming the type?

x = is_voiced<PutTypeNameHere>(superFrame_, etc);

Are the definitions and calling done from the same dll/exe? If not, you may need to explicitly instantiate the template functions with the types you're calling them with.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文