C++ – Are All constexpr Variables Implicitly Inline?

c++c++17inline-variablelinkage

I was playing around with auto template parameters and I was surprised that this code didn't compiled:

constexpr auto bar = 2;

template<auto& T>
struct Foo {
    auto operator()() const { return T; }
};

int main() {
    Foo<bar> b;
    b();
}

Visual Studio 15.7 (preview 4) spit out these errors:

error C2970: 'Foo': template parameter 'T': 'bar': an expression involving objects with internal linkage cannot be used as a non-type argument
 note: see declaration of 'Foo'
 note: see declaration of 'bar'
error C2440: 'specialization': cannot convert from 'int' to 'int &'
 note: see reference to class template instantiation 'Foo<0>' being compiled
error C2973: 'Foo': invalid template argument 'int'
 note: see declaration of 'Foo'

Then, after adding inline, the error got away!

constexpr inline auto bar = 2;

I thought constexpr variables were implicitly inline. Also, how does that affect the linkage of my variable bar?

Best Answer

Are all constexpr variable implicitly inline?

No. Only constexpr functions and constexpr static data members are implicitly inline ([dcl.constexpr]/1).

Also, how does that affect the linkage of my variable bar?

A constexpr variable is const ([dcl.constexpr]/9). A non-inline const variable that is not explicitly declared extern has internal linkage ([basic.link]/3).