包含模板参数的共享库

时间:2015-07-30 16:12:01

标签: c++ templates

使用以下文件

创建共享库
example.cpp
#include <iostream>
template <typename T>
T  Max (T & a, T & b) 
{ 
    return a < b ? b:a; 
} 

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

test.cpp
#include <stdio.h>
#include <iostream>
using namespace std;

template int  Max <int> (int & a, int & b);
template double  Max <double> (double & a, double & b);

int main ()
{
    int i = 39;
    int j = 20;
    cout << "Max(i, j): " << Max(i, j) << endl; 
    double f1 = 13.5; 
    double f2 = 20.7; 
    cout << "Max(f1, f2): " << Max(f1, f2) << endl; 
    return 0;
}

当我编译上面的代码时,得到以下错误

test.cpp:4: error: explicit instantiation of non-template ‘int Max’
test.cpp:4: error: expected ‘;’ before ‘<’ token
test.cpp:5: error: explicit instantiation of non-template ‘double Max’
test.cpp:5: error: expected ‘;’ before ‘<’ token
test.cpp: In function ‘int main()’:
test.cpp:11: error: ‘Max’ was not declared in this scope*

2 个答案:

答案 0 :(得分:3)

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

如果您真的想在标头中提供函数的模板声明,并在共享对象库中提供所述模板的实现,则可以使用显式实例化来实现,看来你正在尝试。但是,您的尝试似乎是在错误的模块中使用了相同的内容。

一种方法如下:

<强> example.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

<强> example.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);

这就是图书馆。使用clang的示例构建将是:

clang++ -std=c++11 -Wall -Wextra -pedantic -fPIC -shared -o libexample.so example.cpp

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

nm libexample.so

0000000000000f50 T __Z3MaxIdET_S0_S0_
0000000000000f20 T __Z3MaxIiET_S0_S0_
                 U dyld_stub_binder

所以你可以看到,他们在lib中。关于将使用此库的测试程序:

<强> TEST.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;
}

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

clang++ -std=c++11 -Wall -Wextra -pedantic -L. -o test -lexample test.cpp

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

Max(i, j): 39
Max(f1, f2): 20.7

老实说,以这种方式做这件事并没有太多的价值,因为明确列表中未提供的Max的任何未来用法都会导致链接器错误(除非这是意图,在哪种情况下它会完全符合您的要求)。

答案 1 :(得分:1)

我的推荐:

  • example.cpp更改为标题文件,Max是模板函数
  • 删除代码中的前向声明
  • 删除#include <stdio.h>,除非确实在某处使用

example.hpp:

template <typename T>
T Max (T& a, T& b)
{
    return a < b ? b : a;
}

TEST.CPP:

#include <iostream>

using namespace std;

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

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

    double f1 = 13.5;
    double f2 = 20.7;

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

    return 0;
}