在库中使用模板
Using templates in Libraries
设置
a.h
void foo(void);
a.cc
#include "a.h"
void foo(void) { /* do something */ }
这些都被编译到一个名为 libA
的共享库中
b.h
#include "a.h"
void bar(void);
template <typename T>
void baz(void)
{
foo();
}
b.cc
#include "b.h"
void bar(void)
{
foo();
}
这两个被编译到共享库 libB
,并且 link 针对 libA
。
现在我写我的主程序,它是link针对libB
编辑的,但是不是 libA
.
main.cc
#include "b.h"
int main(void)
{
bar(); // Okay, compiles
baz<int>(); // Undefined symbol *foo()*, referenced from void bar<int>() in main-(...)
}
说明
我有点明白,为什么这会引发错误。在 libB
中,我有一个模板声明,可用于实例化函数,尽管它不会在 libB
本身中实例化任何函数。
在 main.cc
中,它实例化了函数 void bar<int>(void)
,然后将其放置在 main.cc
的目标代码中,在那里找不到 libA
s foo()
函数并抛出 linking 错误。
谁会想到呢?如果我 link main.cc
也反对 libB
,它工作得很好。
但是我的问题是:我如何才能有效地使用模板,而不必 link 针对原始库 and/or 必须实例化每个我打算使用 bar<>()
的单一版本?
编辑 - 来自聊天的澄清
目标是允许 libB 提供模板,而不需要在 libB 中显式实例化,并且客户端不需要耦合到 libB 的实现细节。
模板定义是库(在本例中为 libB)的 public 接口的一部分。
将 libB 的客户端与其实现细节(在本例中:对 libA 的依赖)分离的唯一方法是通常的方法:不要创建它们 public。将它们隐藏在 libB 中。如果它们在 b.h 中可见,它们就是 public 界面的一部分。
这种情况下的简单解决方案是在 libB 中提供一个(非模板,非内联)函数,抽象出对 libA 的依赖:
// b.h
void do_fooish_things();
template <typename T>
void baz(void)
{
do_fooish_things();
}
// b.cc
#include <libA/a.h>
void do_fooish_things() {
// hidden implementation detail
libA::foo();
}
设置
a.h
void foo(void);
a.cc
#include "a.h"
void foo(void) { /* do something */ }
这些都被编译到一个名为 libA
b.h
#include "a.h"
void bar(void);
template <typename T>
void baz(void)
{
foo();
}
b.cc
#include "b.h"
void bar(void)
{
foo();
}
这两个被编译到共享库 libB
,并且 link 针对 libA
。
现在我写我的主程序,它是link针对libB
编辑的,但是不是 libA
.
main.cc
#include "b.h"
int main(void)
{
bar(); // Okay, compiles
baz<int>(); // Undefined symbol *foo()*, referenced from void bar<int>() in main-(...)
}
说明
我有点明白,为什么这会引发错误。在 libB
中,我有一个模板声明,可用于实例化函数,尽管它不会在 libB
本身中实例化任何函数。
在 main.cc
中,它实例化了函数 void bar<int>(void)
,然后将其放置在 main.cc
的目标代码中,在那里找不到 libA
s foo()
函数并抛出 linking 错误。
谁会想到呢?如果我 link main.cc
也反对 libB
,它工作得很好。
但是我的问题是:我如何才能有效地使用模板,而不必 link 针对原始库 and/or 必须实例化每个我打算使用 bar<>()
的单一版本?
编辑 - 来自聊天的澄清
目标是允许 libB 提供模板,而不需要在 libB 中显式实例化,并且客户端不需要耦合到 libB 的实现细节。
模板定义是库(在本例中为 libB)的 public 接口的一部分。
将 libB 的客户端与其实现细节(在本例中:对 libA 的依赖)分离的唯一方法是通常的方法:不要创建它们 public。将它们隐藏在 libB 中。如果它们在 b.h 中可见,它们就是 public 界面的一部分。
这种情况下的简单解决方案是在 libB 中提供一个(非模板,非内联)函数,抽象出对 libA 的依赖:
// b.h
void do_fooish_things();
template <typename T>
void baz(void)
{
do_fooish_things();
}
// b.cc
#include <libA/a.h>
void do_fooish_things() {
// hidden implementation detail
libA::foo();
}