模板基类中的静态变量

时间:2018-10-25 14:53:13

标签: c++

这不会打印任何内容:

#include <iostream>

template <typename Derived>
struct A
{
    static int test()
    {
        std::cout << "test" << std::endl;
        return 0;
    }

    static inline int a = test();
};

struct B : public A<B>
{
};

int main(int argc, char** argv)
{
    return EXIT_SUCCESS;
}

但是这样做:

#include <iostream>

template <typename Derived>
struct A
{
};

struct B : public A<B>
{
    static int test()
    {
        std::cout << "test" << std::endl;
        return 0;
    }

    static inline int a = test();
};

int main(int argc, char** argv)
{
    return EXIT_SUCCESS;
}

还有这个:

#include <iostream>

struct A
{
    static int test()
    {
        std::cout << "test" << std::endl;
        return 0;
    }

    static inline int a = test();
};

struct B : public A
{

};

int main(int argc, char** argv)
{
    return EXIT_SUCCESS;
}

不确定原因或解决方法。我需要“派生”类型将其注册到静态表中。

3 个答案:

答案 0 :(得分:2)

第一个代码段不显示任何内容的原因是未实例化静态变量。您必须使用该变量才能实例化它。

[temp.inst]/2

  

类模板专门化的隐式实例化导致   声明的隐式实例,但不是   类的定义,默认参数或noexcept指定符   成员函数,成员类,作用域成员枚举,静态   数据成员,成员模板和朋友

作为解决方法,您可以只使用该变量:

int main(int argc, char** argv)
{
    (void) B::a;
    return EXIT_SUCCESS;
}

答案 1 :(得分:1)

由于A是模板类,因此除非使用静态内联函数/变量,否则实际上不会从模板中实例化它们。因此,您可以例如这个:

#include <iostream>

template <typename Derived>
struct A
{
    static int test()
    {
        std::cout << "test" << std::endl;
        return 0;
    }

    static inline int a = test();
};

struct B : public A<B>
{
    static inline int b = a;
};

int main(int argc, char** argv)
{
    return 0;
}

Demo

答案 2 :(得分:0)

here指出的(自动)解决方案是创建一个使用注册变量的构造函数。另外,仅当构造对象时,变量才会被初始化。

#include <iostream>

template <typename Derived>
struct A
{
    A()
    {
        a = 0;
    }

    static int test()
    {
        std::cout << "test" << std::endl;
        return 0;
    }

    static inline int a = test();
};

struct B : public A<B>
{
};

int main(int argc, char** argv)
{
    B b;

    return EXIT_SUCCESS;
}

“ a = 0”是为了避免出现未使用变量的警告。开销应该很小。

Demo