具有显式模板实例化的未解析的外部。声明语法是什么?

发布于 2024-08-26 19:07:08 字数 1280 浏览 5 评论 0原文

这是一些简化的代码来演示我遇到的问题。

我有一个模板函数,我只想编译某些固定的实例。

函数声明为:

// *** template.h ***
int square (int x);
double square (double x);

定义为:

// *** template.cpp ***
#include "template.h"

// (template definition unusually in a code rather than header file)
template <typename T>
T square (T x)
{
    return x*x;
}

// explicit instantiations
template int square (int x);
template float square (float x);

并且,使用示例为:

// *** main.cpp ***

#include <iostream>
using namespace std;

#include "template.h"

int main (void)
{
    cout << square(2) << endl;
    cout << square(2.5) << endl;
}

尝试编译此结果会导致链接错误,大致如下:

main.obj:函数 main 中引用的未解析的外部符号“int square(int)”

我明白问题是什么:我的显式模板实例化的函数签名与头文件中的函数签名不匹配。

请问显式模板实例化的(前向)声明的语法是什么?我不想转发声明模板定义,或将模板定义移动到头文件中。

对于它的价值,我确实有一个解决方法,即使用包装函数,将以下内容添加到上述文件中:

// *** template.cpp ***

// ...

// wrap them [optionally also inline the templates]
int square (int x) { return square<> (x); }
double square (double x) { return square<> (x); }

编译并按预期工作。然而,这对我来说似乎是一个黑客。 C++ 和模板语法中应该有比这更优雅的东西。

任何帮助或提示将不胜感激。

Here's some simplified code to demonstrate the problem I have.

I have a template function for which I only wish to compile certain fixed instantiations.

The function declarations are:

// *** template.h ***
int square (int x);
double square (double x);

The definitions are:

// *** template.cpp ***
#include "template.h"

// (template definition unusually in a code rather than header file)
template <typename T>
T square (T x)
{
    return x*x;
}

// explicit instantiations
template int square (int x);
template float square (float x);

And, an example use is:

// *** main.cpp ***

#include <iostream>
using namespace std;

#include "template.h"

int main (void)
{
    cout << square(2) << endl;
    cout << square(2.5) << endl;
}

An attempt to compile this results in a link errors, roughly:

main.obj : unresolved external symbol "int square(int)" referenced in function main

I understand what the problem is: the function signatures of my explicit template instantiations do not match those in the header file.

What is the syntax for the (forward) declaration of the explicit template instantiations please? I do not wish to forward declare the template definition, or to move the template definition into a header file.

For what it's worth, I do have a workaround, which is to use wrapper functions, adding the following to the above files:

// *** template.cpp ***

// ...

// wrap them [optionally also inline the templates]
int square (int x) { return square<> (x); }
double square (double x) { return square<> (x); }

That compiles and works as expected. However, this seems like a hack to me. There should be something more elegant than this available in C++ and template syntax.

Any help or hints would be much appreciated.

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

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

发布评论

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

评论(2

漫雪独思 2024-09-02 19:07:08

您需要在标头中声明函数模板:

template <typename T>
T square(T x);

正如您现在所拥有的那样,您在标头中声明了两个从未定义的非模板函数。

You need to declare the function template in your header:

template <typename T>
T square(T x);

As you have it now, you declare two nontemplate functions in the header, which are never defined.

从此见与不见 2024-09-02 19:07:08

如果您想在头文件中隐藏模板,没有其他方法。您必须拥有包装函数,因为 int square (int x); 不具有与 template int square (int x); 相同的名称重整,并且 C++ 不提供此功能改变这一点的方法。

您可以查看 Visual Studio 中名称混合的不同之处 为例。

There is no other way if you want to hide the template from the header file. You have to have wrapper functions because int square (int x); does not have the same name mangling as template int square (int x); and C++ does not offer you a way to change that.

You can check out how name mingling differs in Visual Studio as an example.

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