C++ 如何使用C++;11个减少二进制大小的显式模板?

C++ 如何使用C++;11个减少二进制大小的显式模板?,c++,c++11,templates,C++,C++11,Templates,我不熟悉显式模板的概念,在使用它和看到二进制大小的任何差异时遇到了麻烦。 我编写的简单代码如下所示: comp.cc: #include "comp.h" using namespace std; template <typename T> int compare(const T& x, const T& y) { return x < y ? 0 : 1; } int func()

我不熟悉显式模板的概念,在使用它和看到二进制大小的任何差异时遇到了麻烦。 我编写的简单代码如下所示:

comp.cc:

  #include "comp.h"

    using namespace std;

    template <typename T>
    int compare(const T& x, const T& y)
    {
        return x < y ? 0 : 1;
    }


    int func()
    {
        compare(10,9);
        compare(1.5, 7.8);
    }
#包括“comp.h”
使用名称空间std;
模板
整数比较(常数T&x、常数T&y)
{
返回x
公司h:

template <typename T>
int compare(const T& x, const T& y);
模板
整数比较(常数T&x、常数T&y);
main.cc:

#include "comp.h"
#include <iostream>

using namespace std;

extern template int compare(const int&, const int&);
extern template int compare(const double&, const double&);

int main()
{
    compare(10,9);
    cout << compare(1.5, 7.8) << endl;
    return 0;
}
#包括“comp.h”
#包括
使用名称空间std;
外部模板int比较(常量int&,常量int&);
外部模板int比较(常数双精度,常数双精度);
int main()
{
比较(10,9);

cout您实际上可以通过显式模板实例化来减少代码大小,但是,您需要一个更复杂的用例:假设您有一个模板类,该类在文件
comp.cc
的代码中定义,并在文件
comp.h
中声明,并且您希望将该类与公共安装(模板参数)一起使用在多个可执行文件中,则可以

  • 显式实例化常用模板
  • 将此对象代码捆绑到共享对象(动态链接/共享库)中,然后
  • 通过链接共享库,使用可执行文件中的这些实例化
  • 相反,如果您将在可执行文件的代码中直接使用模板安装(通过包括也包含模板定义的文件,而不仅仅是它们的声明),那么您将有多个(相等的)模板安装,每个可执行文件中都有一个,从而产生一个更大的总体目标代码大小

    例如,您的显式模板安装将转到
    comp.cc
    。请注意,我将函数从
    compare
    重命名为
    less
    ,因为只说“compare”并不太详细(我们如何比较?),并且我将返回值从
    int
    更改为
    bool

    #include "comp.h"
    
    using namespace std;
    
    template <typename T> bool my_less(const T& x, const T& y)
    {
        return x < y;
    }
    
    // explicit instatiations
    template bool my_less<int>(const int& x, const int& y); // you may omit <int> here
    template bool my_less<double>(const double& x, const double& y); // you may omit <double> here
    
    所有这些都将使用以下
    Makefile
    进行编译和链接。请注意,我在Linux系统上使用GNU Make,因此如果您使用不同的系统,您的方法可能会有所不同:

    CXXFLAGS = -O3 -g -Wall -Wextra -std=c++11
    
    LDFLAGS += -L.
    
    comp.o : CXXFLAGS += -fPIC
    
    libmy_comp.so : comp.o
        $(CXX) -shared -o $@ $<
    
    main1 main2 : LDLIBS += -lmy_comp
    main1 main2 : libmy_comp.so
    
    同样地,
    main2.cc
    将是:

    #include "comp.h"
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        cout << boolalpha << my_less(10,9) << "\n";
        cout << my_less(1.5, 7.8) << endl;
        return 0;
    }
    
    #包括“comp.h”
    #包括
    使用名称空间std;
    int main()
    {
    
    是的,您缺少了一些简单的东西:在现代实现中,显式模板声明与二进制大小完全无关,链接器将在链接阶段自动消除重复的模板实例。这就是链接器的用途。@SamVarshavchik:如果没有人可以lled̀比较`(nor
    main
    ,nor
    func
    )?然后显式声明将使二进制大小变大,因为它将生成
    比较
    的代码,而如果没有显式声明,则不会生成此代码?那么,如果链接器为我的任务执行此操作,我从使用此功能中得到了什么?@samvarshavchikt从此功能中获得的唯一东西只对ve有意义Ry,非常大,复杂,C++代码库,保存编译器在每个编译单元中烧录CPU模板的问题,在编译时节省的时间通常很小,但有时需要大量编译的C++代码,节省每一点点的帮助。这是C++所需要的。+.
    int compare(const int&,const int&)
    是一个普通函数。与任何其他函数没有区别。单个函数必须始终具有相同的地址、相同的指针。
    #include "comp.h"
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        my_less(10,9);
        cout << boolalpha << my_less(1.5, 7.8) << endl;
        return 0;
    }
    
    #include "comp.h"
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        cout << boolalpha << my_less(10,9) << "\n";
        cout << my_less(1.5, 7.8) << endl;
        return 0;
    }