Skip to main content
deleted 6 characters in body; added 16 characters in body
Source Link
PcAF
  • 2k
  • 13
  • 21

To explain what's happening here:

You declared static const integer inside class, this "feature" is here because you're thento be able to use it as constant expression,e.i.e. for local array size, template non-type parameters, etc.. If compiler wants to use this constant expression it must be able to see it's value in that translation unit.

9.5/3

If a non-volatile const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment� expression is a constant expression (5.19). A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. — end note ] The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer.

odr-used means to form reference to that variable or take it's address.

std::min takes it's parameters by reference, so they are odr-used.

Solution:

Define it!

class A
{
    static const int a = 5;
};

const int A::a; //definition, shall not contain initializer

To explain what's happening here:

You declared static const inside class, this "feature" is here because you're then able to use it as constant expression,e.i. for local array size, template non-type parameters, etc.. If compiler wants to use constant expression it must see it's value in that translation unit.

9.5/3

If a non-volatile const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment� expression is a constant expression (5.19). A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. — end note ] The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer.

odr-used means to form reference to that variable or take it's address.

std::min takes it's parameters by reference, so they are odr-used.

Solution:

Define it!

class A
{
    static const int a = 5;
};

const int A::a; //definition, shall not contain initializer

To explain what's happening here:

You declared static const integer inside class, this "feature" is here to be able to use it as constant expression,i.e. for local array size, template non-type parameters, etc.. If compiler wants to use this constant expression it must be able to see it's value in that translation unit.

9.5/3

If a non-volatile const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment� expression is a constant expression (5.19). A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. — end note ] The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer.

odr-used means to form reference to that variable or take it's address.

std::min takes it's parameters by reference, so they are odr-used.

Solution:

Define it!

class A
{
    static const int a = 5;
};

const int A::a; //definition, shall not contain initializer
Source Link
PcAF
  • 2k
  • 13
  • 21

To explain what's happening here:

You declared static const inside class, this "feature" is here because you're then able to use it as constant expression,e.i. for local array size, template non-type parameters, etc.. If compiler wants to use constant expression it must see it's value in that translation unit.

9.5/3

If a non-volatile const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment� expression is a constant expression (5.19). A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. — end note ] The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer.

odr-used means to form reference to that variable or take it's address.

std::min takes it's parameters by reference, so they are odr-used.

Solution:

Define it!

class A
{
    static const int a = 5;
};

const int A::a; //definition, shall not contain initializer