在 cpp 文件中隐藏采用模板参数引用的方法

Hide method taking template parameter reference in cpp file

本文关键字:参数 引用 方法 文件 cpp 隐藏      更新时间:2023-10-16

我想使用 C++11 隐藏我的函数在相应的 cpp 文件中引用模板参数。但我总是以缺少引用链接器错误告终。只有当我将定义复制到 a.h 文件但我想隐藏代码时,它才明显有效。否则,使用模板对象作为参数会迫使我将大量项目代码放入头文件中。有什么方法可以存档吗?

相关内容:在 中存储C++模板函数定义。CPP 文件。但这里的模板是类型名而不是大小。

这是我显示我的问题的最小示例。

B.H

#ifndef _B_EXAMPLE_H
#define _B_EXAMPLE_H
#include <cstdint>
#include <cstring>
template<std::uint32_t T>
class B
{
private:
char x[T];
public:
void add(const char* str)
{
strncpy(this->x, str, T - 1);
}
};
#endif

A.H

#ifndef _A_EXAMPLE_H
#define _A_EXAMPLE_H
#include "b.h"
#include <cstdint>
class A
{
public:
template<std::uint32_t T> void foo(B<T>& t);
};
#endif

答.cpp

#include "a.h"
template<std::uint32_t T> void A::foo(B<T>& obj)
{
obj.add("Top secret");
}

主.cpp

#include "a.h"
int main()
{
B<20> bObj;
A aObj;
aObj.foo(bObj);
return 1;
}

编辑

即使这个问题已经关闭,我也想在这里分享我的解决方案。在我看来,我的问题相关但不相同。

B.H

#ifndef _B_EXAMPLE_H
#define _B_EXAMPLE_H
#include <cstdint>
#include <cstring>
class B
{
private:
char* const x;
const std::uint32_t xLen;
public:
B(char* x, std::uint32_t len) : x(x), xLen(len) {}
virtual ~B() {}
void add(const char* str)
{
strncpy(this->x, str, this->xLen - 1);
}
};
template<std::uint32_t T>
class GenB : public B
{
public:
char myBuf[T];
GenB() : B(myBuf, T) {}
};
#endif

A.H

#ifndef _A_EXAMPLE_H
#define _A_EXAMPLE_H
#include "b.h"
#include <cstdint>
class A
{
public:
void foo(B& t);
};
#endif

答.cpp

#include "a.h"
void A::foo(B& obj)
{
obj.add("Top secret");
}

主.cpp

#include "a.h"
int main()
{
GenB<20> bObj;
A aObj;
aObj.foo(bObj);
return 1;
}

在你的特定情况下,你不能。您可以在.cpp中对非类型模板参数 T 的某些值执行显式模板实例化。如果您在程序的其余部分的任何地方都使用这些值,则可以。但是,我假设这不是您想要的,并希望可以自由地为 T 指定任何值。如果是这种情况,您必须将模板的定义放在模板用户可访问的某个位置(通常在 .h( 文件中。

有些人所做的只是为了可读性,将模板的定义放入一个 .inl 文件中,该文件作为声明模板的 .h 的最后一行包含在内。 这不会以任何方式改变限制,只是为您提供了一些分离。如果要将其作为库交付,则需要向客户提供 .h 和 .inl 文件。

如果你想做显式实例化,在你的cpp中,它看起来像这样:

template class B<20>;

然后,如果您仅在以 20 作为非类型模板参数的版本中使用类 B,则可以使用它(任何其他值都会导致您当前看到的相同错误(