带有模板参数的共享库

Ani*_*tha 4 c++ templates

使用以下文件创建共享库

\n\n
example.cpp\n#include <iostream>\ntemplate <typename T>\nT  Max (T & a, T & b) \n{ \n    return a < b ? b:a; \n} \n
Run Code Online (Sandbox Code Playgroud)\n\n

我试图在我的代码中使用上面的库

\n\n
test.cpp\n#include <stdio.h>\n#include <iostream>\nusing namespace std;\n\ntemplate int  Max <int> (int & a, int & b);\ntemplate double  Max <double> (double & a, double & b);\n\nint main ()\n{\n    int i = 39;\n    int j = 20;\n    cout << "Max(i, j): " << Max(i, j) << endl; \n    double f1 = 13.5; \n    double f2 = 20.7; \n    cout << "Max(f1, f2): " << Max(f1, f2) << endl; \n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

当我编译上面的代码时,出现以下错误

\n\n
test.cpp:4: error: explicit instantiation of non-template \xe2\x80\x98int Max\xe2\x80\x99\ntest.cpp:4: error: expected \xe2\x80\x98;\xe2\x80\x99 before \xe2\x80\x98<\xe2\x80\x99 token\ntest.cpp:5: error: explicit instantiation of non-template \xe2\x80\x98double Max\xe2\x80\x99\ntest.cpp:5: error: expected \xe2\x80\x98;\xe2\x80\x99 before \xe2\x80\x98<\xe2\x80\x99 token\ntest.cpp: In function \xe2\x80\x98int main()\xe2\x80\x99:\ntest.cpp:11: error: \xe2\x80\x98Max\xe2\x80\x99 was not declared in this scope*\n
Run Code Online (Sandbox Code Playgroud)\n

Who*_*aig 6

我意识到这是一个微不足道的例子,更多的是出于学术目的。否则我建议放弃整个事情并std::max从一开始就使用。标准库提供了大量明确且经过测试的功能供使用;除非你有充分的理由重新发明轮子,否则请使用它。

如果您确实想在标头中提供函数的模板声明,并在共享对象库中提供 said-template 的实现,则可以通过使用显式实例化来实现,这似乎是您正在尝试的。但是,您的尝试似乎将 said-same 放入了错误的模块中。

一种方法如下:

示例.hpp

#ifndef MYLIB_EXAMPLE_HPP
#define MYLIB_EXAMPLE_HPP

// define forward declaration here. no implementation
template<class T> T Max(T lhs, T rhs);

#endif
Run Code Online (Sandbox Code Playgroud)

示例.cpp

#include "example.hpp"

// provide implementation here    
template<class T>
T Max(T lhs, T rhs)
{
    return (lhs < rhs) ? rhs : lhs;
}

// explicit instantiations
template int Max<int>(int,int);
template double Max<double>(double,double);
Run Code Online (Sandbox Code Playgroud)

这就是图书馆的内容。使用的示例构建clang如下:

clang++ -std=c++11 -Wall -Wextra -pedantic -fPIC -shared -o libexample.so example.cpp
Run Code Online (Sandbox Code Playgroud)

生成的共享对象库公开以下符号:

nm libexample.so

0000000000000f50 T __Z3MaxIdET_S0_S0_
0000000000000f20 T __Z3MaxIiET_S0_S0_
                 U dyld_stub_binder
Run Code Online (Sandbox Code Playgroud)

如您所见,它们就在库中。进入将使用该库的测试程序:

测试.cpp

#include <iostream>
#include "example.hpp"

int main ()
{
    int i = 39;
    int j = 20;

    std::cout << "Max(i, j): " << Max(i, j) << std::endl;

    double f1 = 13.5;
    double f2 = 20.7;

    std::cout << "Max(f1, f2): " << Max(f1, f2) << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我们按如下方式构建它(假设库位于本地文件夹中):

clang++ -std=c++11 -Wall -Wextra -pedantic -L. -o test -lexample test.cpp
Run Code Online (Sandbox Code Playgroud)

生成的程序test产生以下输出:

Max(i, j): 39
Max(f1, f2): 20.7
Run Code Online (Sandbox Code Playgroud)

老实说,这样做没有太多价值,因为Max您的显式列表中未提供的任何未来用法都将导致链接器错误(除非这是意图,在这种情况下,它将完全按照您的方式进行操作)正在寻找)。