¿La metaprogtwigción con estado está mal formada (todavía)?

Uno de mis inventos más queridos / malvados que he tenido la fortuna de encontrar es el contador de constelaciones , también conocido como metaprogtwigción con estado. Como se menciona en la publicación, parece ser legal en C ++ 14, y me pregunto si algo ha cambiado con C ++ 17.

La siguiente es una implementación en gran medida basada en la publicación

template  struct flag { friend constexpr int adl_flag(flag); constexpr operator int() { return N; } }; template  struct write { friend constexpr int adl_flag(flag) { return N; } static constexpr int value = N; }; template <int N, int = adl_flag(flag{})> constexpr int read(int, flag, int R = read(0, flag{})) { return R; } template  constexpr int read(float, flag) { return N; } template  constexpr int counter(int R = write<read(0, flag{}) + N>::value) { return R; } 

Y lo usamos como

 static_assert(counter() != counter(), "Your compiler is mad at you"); template struct S {}; static_assert(!std::is_same_v<S, S>, "This is ridiculous"); 

Esto, por cierto, ¿es una contradicción directa para el almacenamiento de estados en la metaprogtwigción C ++?

Este es el problema activo de CWG 2118 :

Definir una función amiga en una plantilla, luego hacer referencia a esa función más adelante proporciona un medio para capturar y recuperar el estado de la metaprogtwigción. Esta técnica es arcana y debe hacerse mal formada.

Notas de la reunión de mayo de 2015:

CWG acordó que tales técnicas deberían estar mal formadas, aunque el mecanismo para prohibirlas aún no está determinado.

Todavía es un problema activo, nada cambiará en C ++ 17 al menos por ahora. Sin embargo, cuando se determina un mecanismo de prohibición de este tipo, este puede ser gobernado retroactivamente como un DR.