What are rules for a class static variable initialization?

前端 未结 2 506
别跟我提以往
别跟我提以往 2021-01-14 12:15

I have some legacy code and I need to add a new class for the message (which is irrelevant to my question). But it turns out that I need to declare an empty constructor in o

相关标签:
2条回答
  • 2021-01-14 12:44

    C++14 [temp.inst]/2:

    Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist; in particular, the initialization (and any associated side-effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.

    This says clearly that Message<A>::test will not be initialized unless it is used in a way that requires its definition to exist.

    The only expression in your program that would require the definition is test.dummy() in the constructor of Message<A> ; so if that expression is removed then test must not be initialized.

    For the case where test.dummy() is present, note that it is inside a template function, the constructor of Message<A>. If this constructor is never instantiated, then test.dummy() will not be considered.

    As pointed out by VTT, [class.ctor] says that the explicitly-defaulted constructor for A means that no constructor is defined unless an A is odr-used.

    Your code doesn't odr-use an A, therefore A's constructor is not defined, therefore there is no invocation of base class constructor (which would only happen if if A's constructor was defined), therefore the constructor template Message<A>() is not instantiated, therefore test is not required to exist.

    0 讨论(0)
  • 2021-01-14 13:00

    If you leave A constructor defaulted and never call it then there is no need to generate it and therefore no need to create test. If you explicitly default it at definition, call A constructor or access A::test it will be initialized properly.

    12.1 Constructors [class.ctor]

    7 A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used (3.2) to create an object of its class type (1.8) or when it is explicitly defaulted after its first declaration.

    struct A : public Message<A>
    {
        A() = default; // no constructor is emitted unless A is instantiated
    
        A(); // declaration
    };
    
    A::A() = default; // explicit default definition
    
    int
    main()
    {
        A a; // instantiation
        A::test; // just explicitly access test so it is initialized regardless of A constructor
    }
    
    0 讨论(0)
提交回复
热议问题