user975989
user975989

Reputation: 2648

Does redeclaring a static const member as constexpr automatically qualify it to be inline?

Consider this use case of a static constexpr member:

// smart_enum.h
class smart_enum {
    // Some data, operations, etc.
    // Cannot use constexpr here, smart_enum is incomplete at this point
    static const smart_enum first, second;
};

constexpr smart_enum smart_enum::first = {}, smart_enum::second = {};

Are first and second automatically inline variables? Or do I need to qualify them as such? Or am I unable to qualify them as inline and need to provide a definition in some source file later? I have always been confused by this "redefinition" from const to constexpr and would like more light to be shed on what this really means.

Specifically I am wondering about the interaction of const declaration to constexpr definition and how that plays out with automatic inline of a static constexpr (Redefinitions of constexpr static data members are allowed now? (but not inline const)?)

Upvotes: 1

Views: 269

Answers (2)

Davis Herring
Davis Herring

Reputation: 40023

In C++14, no variables are inline, of course. Making variables like this automatically inline was an unintentional breaking change (since it means that the definition must appear in every translation unit). I filed CWG2531 to try to have this rectified. There are now of course backwards-compatibility concerns with C++17 implementations, although any code that wants the other behavior can just add inline to the out-of-class definition as is already allowed.

Upvotes: 1

Massimiliano Janes
Massimiliano Janes

Reputation: 5624

the standard says:

[c++17-12.2.3.2-2]The declaration of a non-inline static data member in its class definition is not a definition and may be of an incomplete type other than cv void.

now, maybe your confusion stems from believing that the two expressions

static const smart_enum first; // class scope
constexpr smart_enum smart_enum::first = ...; // namespace scope

declare different types. This is not the case because the type of a constexpr T is still const T ( in fact you can always write constexpr const T to mean the same thing ).

So, in your code, you first declare a name 'first' of incomplete type 'const smart_enum', then you leter define it as "constexpr smart_enum" ( or "constexpr inline const smart_enum" if we add everything constexpr implies explictly ).

Upvotes: 1

Related Questions