CRTP模式不会触发完整的模板实例化

我已经创建了一个模板类,该模板类会在发生实例化时触发运行时文本输出:

template<typename T>
struct verbose {
    verbose()
    {
        std::cout << "Instantation occured!" << std::endl;
    }
};

template<typename T>
struct base
{
    inline static verbose<T> v;
};

当我强制创建实例时,它显示输出:

template struct base<int>;
//output: Instantation occured!

Check on Wandbox)。

另一方面,当我将其与CRTP模式一起使用时,似乎没有实例化:

class test : public base<test>
{
};

Check on Wandbox

这种行为是否符合ISO标准?我可以以某种方式强制进行实例化,而无需模板类(base)的用户编写其他代码吗?对我来说,重要的是静态变量构造函数的副作用。

yk8278 回答:CRTP模式不会触发完整的模板实例化

您的CRTP使用情况属于隐式实例化:

当代码在需要完全定义的类型的上下文中引用模板时,或者当类型的完整性影响代码并且尚未显式实例化此特定类型时,将发生隐式实例化。例如,当构造这种类型的对象时,而不是在构造指向这种类型的指针时。

这适用于类模板的成员:除非在程序中使用了该成员,否则不会实例化该成员,并且不需要定义。
cppreference

在第二段之后,由于实际上从未使用过base<test>::v,因此实际上没有发生base<test>::v的实例化。

由于需要使用用法来生成其实例,因此将需要其他代码来获得所需的输出。例如,您可以向base添加一个构造函数:

template<typename T>
struct base
{
    inline static verbose<T> v;
    base() { (void)&v; }
};

仅凭test本身的定义,这还不足以触发您的输出。但是,如果您的程序尝试从test创建对象,则构造函数的形成将导致使用模板的构造函数,因此将base<test>::v实例化。

本文链接:https://www.f2er.com/2795953.html

大家都在问