模板显式实例化如何工作?

How template explicit instantiation works?

我正在努力理解使用 extern 说明符的模板显式实例化。这是我的例子

// power.h

template <typename T>
class Power
{
public:
    T operator()(T const& x) {return x * x;}
};

// power.cpp

#include "power.h"

template
class Power<int>;

//mathlib.h

class Square
{
public:
    Square(int);
    inline int side()const { return side_;}
    int surface()const;
    int perim()const;

private:
    int side_{};
};

// mathlib.cpp

#include "mathlib.h"
#include "power.h"

extern template class Power<int>;

Square::Square(int x) :
    side_(x)
{}

int Square::surface() const
{
    return Power<int>{}(side_);
}

int Square::perim() const
{
    return side_ * 4;
}

//physiqlib.h

class Planet
{
public:
    Planet(int);
    int velocity()const;

private:
    int veloc_{};
};

//physiqlib.cpp

#include "physiqlib.h"
#include "power.h"

extern template class Power<int>;


Planet::Planet(int v) :
    veloc_(v)
{}

int Planet::velocity()const
{
    return Power<int>{}(veloc_);
}

//main.cpp

#include <iostream>
#include "mathlib.h"
#include "physiqlib.h"
#include "power.h"

int main()
{

    Square sq{7};
    std::cout << "side: " << sq.side() << '\n';
    std::cout << "surface: " << sq.surface() << '\n';
    std::cout << "perim: " << sq.perim() << '\n';

    std::cout << '\n';
    std::cout << "Planet name: Earth\n";
    Planet plEarth(150000);
    std::cout << "velocity: " << plEarth.velocity() << '\n';

    std::cout << "\ndone!\n";
}

** 如果我从终端编译程序生成中间文件:g++ -S -save-temps main.cpp physiqlib.cpp power.cpp mathlib.cpp 为什么我在每个 *.ii 中得到一个模板定义 class Power?像这样:

// mathlib.ii

# 1 "mathlib.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "mathlib.cpp"
# 1 "mathlib.h" 1
    

class Square
{
public:
    Square(int);
    inline int side()const { return side_;}
    int surface()const;
    int perim()const;

private:
    int side_{};
};
# 2 "mathlib.cpp" 2
# 1 "power.h" 1



template <typename T>
class Power
{
public:
    T operator()(T const& x) {return x * x;}
};
# 3 "mathlib.cpp" 2

extern template class Power<int>;

Square::Square(int x) :
    side_(x)
{}

int Square::surface() const
{
    return Power<int>{}(side_);
}

int Square::perim() const
{
    return side_ * 4;
}

非常感谢!

I want to know whether this is how Explicit instantiation works or not?

是的。

Why I get in each *.ii a definition of the template class Power?

*.ii 文件是预处理阶段的结果。与模板实例化无关。

Does this mean the class template Power is only defined but not yet instantiated and the instantiation class Power is elsewhere?

是的,调用 return Power<int>{}(side_);

没有完成隐式实例化

If I am correct is this technique available by the new standard to avoid template code bloat?

它可能会减少一些,它节省了编译时间,因为只实例化了一次。 即使在单个翻译单元中,多个实例化仍可能会发生代码膨胀。

有关 class_template#Explicit_instantiation

的更多详细信息