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
?
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).