2

N4687:


[Annex D (normative) Compatibility features]

D.1 Redeclaration of static constexpr data members

1 For compatibility with prior C++ International Standards, a constexpr static data member may be redundantly redeclared outside the class with no initializer. This usage is deprecated. [ Example:

struct A {
static constexpr int n = 5; // definition (declaration in C++ 2014)
};

constexpr int A::n; // redundant declaration (definition in C++ 2014)

— end example ]


I don't have a good command of English, so I am confronted with several questions when learning standard(I'm just coming from odr-use)

  1. This usage is deprecated which usage does here mean?

    • definition (declaration in C++ 2014)
    • redundant declaration (definition in C++ 2014)

the two comments confuse me. Here is two possibility:

i.

  • Until C++ 2014(c++14/1y), static constexpr int n = 5; is a definition. constexpr int A::n; is a redundant declaration.

  • Since C++17(or after c++14), static constexpr int n = 5; is a declaration. constexpr int A::n; is a definition

ii.

  • Since C++17(or after c++14), static constexpr int n = 5; is a definition. constexpr int A::n; is a redundant declaration.

  • Before c++17(which include c++ 2014), static constexpr int n = 5 is a declaration. constexpr int A::n; is a definition.

i and ii, which is true?

陳 力
  • 4,063
  • 1
  • 18
  • 41

2 Answers2

1
  1. Redeclaring the constexpr static data member outside the class is deprecated. That is, in C++17 you should only have the definition inside the class and nothing outside.

  2. Second option: C++17 makes the in-class thingy a definition, and the outer thingy a redundant declaration.
    The parentheses recall that in C++14, they were respectively a declaration and a definition.

Quentin
  • 58,778
  • 7
  • 120
  • 175
  • Thanks for your answer. I still have a question: Now that redeclaring is deprecated in c++17, why c++17 modify `definition` to `redundant declaration`(just as option2 mentions)? It is a conflict, isn't? – 陳 力 Nov 13 '17 at 13:14
  • @czxyl because if the out-of-class one was still a definition, you'd get two definitions, which is an ODR error. Hence the "redundant declaration" wording that essentially means ignoring it. – Quentin Nov 13 '17 at 13:17
0

Neither is really correct. I found a good explanation of definition and declaration in this answer:

Declaration "Somewhere, there exists a foo".

Definition: "...and here it is!"

For regular class members, they can be declared in the header file and defined in the implementation (cpp) file.

What C++17 changes is that when you provide a compile-time constant as the value for that class member, it is a definition and you are defining it in the class definition. You can neither redefine it outside of the class, nor redeclare it.

This usage is deprecated which usage does here mean?

Usage refers to the redeclaration.

mrks
  • 6,996
  • 26
  • 48