共享库中的c++模板专门化——调用专门化函数不起作用



我确实在库中有一个模板化的函数以及它的专门化我想链接到另一个项目。下面是一个最小的例子——模板的专门化按预期工作。

lib.h

#include <iostream>
template <typename T>
void f(T t)
{
std::cout << "generic templaten";
}

lib.cpp

#include "lib.h"
template <>
void f(int t)
{
std::cout << "integer specializationn";
}
int main()
{
double d = 3.0;
int i = 3;
f(d);
f(i);
}

输出
generic template
integer specialization

在下一步中,我将库编译为共享库(注释main函数)

g++ -fPIC -c -o lib.o lib.cpp
g++ -shared lib.o -o libLIB.so

main.cpp

#include "lib.h"
int main()
{
double d = 3.0;
int i = 3;
f(d);
f(i);
}

编译main和链接LIB

g++ -L . main.cpp -lLIB

使用lib作为共享库时,函数特化不能按预期工作。输出:

generic template
generic template

我知道只需将专门化模板移动到lib.h文件中就可以解决这个问题。但我希望将专门化保存在单独的.cpp文件中。有人能解释这种行为吗?

你差一点就成功了。

您必须删除泛型实现并添加双精度,如下所示:

lib.h

template <typename T>
void f(T t);

lib.cpp

#include "lib.h"
#include <iostream>
template <>
void f(int t)
{
std::cout << "integer specializationn";
}
template <>
void f(double t)
{
std::cout << "double specializationn";
}

main.cpp

#include "lib.h"
int main()
{
double d = 3.0;
int i = 3;
f(d);
f(i);
}

使用

编译并运行
$ g++ -fPIC -shared lib.cpp -o libtest.so
$ g++ -fPIC main.cpp -L. -l test -o main
$ LD_LIBRARY_PATH=. ./main
double specialization
integer specialization

或者(如您所建议的),您可以定义一个泛型实现,并让编译器知道您在其他地方定义了专门化。

lib.h

#include <iostream>
template <typename T>
void f(T t) {
std::cout << "Generic implementationn";
}
template<>
void f( double t );
template<>
void f( int t );

lib.cpp

#include "lib.h"
template <>
void f(int t)
{
std::cout << "integer specializationn";
}
template <>
void f(double t)
{
std::cout << "double specializationn";
}

main.cpp

#include "lib.h"
int main()
{
double d = 3.0;
int i = 3;
float x = 0;
f(d);
f(i);
f("string");
f(x);
}

编译并运行:

$ g++ -fPIC -shared lib.cpp -o libtest.so
$ g++ -fPIC main.cpp -L. -l test -o main
$ LD_LIBRARY_PATH=. ./main
double specialization
integer specialization
Generic implementation
Generic implementation

最新更新