As far as I can see, a very common situation is something like
template<int i> class Class
{
public:
static constexpr int I = i;
static constexpr int J = constexprFunction(i);
// further Class implementation
};
Almost as common I see the mistake (in fact most of my questions here are because I forgot it and did not know, what the proper question had been) to forget the additional definition if the member are odr-used:
template<int i> constexpr int Class<i>::I;
template<int i> constexpr int Class<i>::J;
Now I read cppreference: Definitions and ODR and cppreference: static members, which state, that this is deprecated for C++17. This seems great to me, because it avoids a lot of errors. But there are other questions, that came up:
1) Has this change other reasons than making the additional definitions useless? (See also last paragraph of this question)
2) In the last example of cppreference: static members it seems also to apply on const static
member - but the rule states only the constexpr
member. Will it apply on const static
member or not?
3) All examples I found were using a simple definition like Class::I
- does it all hold also for the situation at Class:J
with constexpr
functions?
A brief state what the best practices are before C++17 and with C++17 would be great. All in all this seems a very tricky change to me, because it will make a lot of code, which was "ill-formed non diagnostic required" before, to good code (as far as I understand...). And consequently there will be code produced, that is still "ill-formed non diagnostic required" with older (pre 17) compiler - but these will not complain, as long as no odr-use is required.
Edit: Corrected the text, suggested by Aaron McDaid.
This change is due to the inline variables proposal (P0386).
static constexpr
will implyinline
, making definitions redundant.Regarding to your questions:
In essence, no. Yet it has additional uses besides the one you noted (see this question). This proposal was controversial because it might encourage the use of a mutable global state.
No. Unless you annotate it as
inline
.Yes. The proposal deals with linking but does not affect initialization rules.