【问题标题】:Static variable inside a template base class模板基类中的静态变量
【发布时间】:2018-10-25 14:53:12
【问题描述】:

这不打印:

#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;
}

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

【问题讨论】:

  • 第二个有什么问题?
  • @user463035818 想必你必须在每个派生类中编写它。
  • @MaxLanghof 如果test 放在(非模板化)基类中,则不会

标签: c++


【解决方案1】:

第一个sn-p不打印任何东西的原因是静态变量没有实例化。您必须使用该变量来实例化它。

[temp.inst]/2

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

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

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

【讨论】:

  • 是的,隐含的问题是为什么没有初始化变量。这个想法是避免任何其他代码,以便为每个派生类自动执行静态函数。
【解决方案2】:

由于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

【讨论】:

  • 这个想法是自动化。
  • @chila 那么为什么不使用this之类的答案呢?
  • 所有继承自模板类的类的注册应在程序启动时进行,在 main 执行之前。
  • 我想在静态集中注册类类型。
  • 这听起来和我链接的答案一模一样...你读了吗?
【解决方案3】:

正如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

【讨论】:

    猜你喜欢
    • 2019-05-10
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 2019-06-21
    相关资源
    最近更新 更多