c++ - A metaprogramação stateful está mal formada(ainda)?



language-lawyer metaprogramming (1)

Esta é a edição ativa do CWG 2118 :

Definindo uma função de amigo em um modelo, referenciar essa função posteriormente fornece um meio de capturar e recuperar o estado de metaprogramação. Essa técnica é arcana e deve ser mal formada.

Notas da reunião de maio de 2015:

O CWG concordou que tais técnicas deveriam ser mal formadas, embora o mecanismo para proibi-las seja ainda indeterminado.

Ainda é um problema ativo, nada vai mudar em C ++ 17 pelo menos por agora. Embora quando tal mecanismo de proibição seja determinado, este pode ser retroativamente governado como um DR.

Uma das minhas invenções mais amadas / más que tive a sorte de encontrar é o contador constexpr , também conhecido como metaprogramação stateful. Como mencionado no post, parece ser legal em C + + 14, e eu estou querendo saber alguma coisa mudou com o C + + 17?

A seguir, uma implementação amplamente baseada no post

template <int N>
struct flag
{
    friend constexpr int adl_flag(flag<N>);
    constexpr operator int() { return N; }
};

template <int N>
struct write
{
    friend constexpr int adl_flag(flag<N>) { return N; }
    static constexpr int value = N;
};

template <int N, int = adl_flag(flag<N>{})>
constexpr int read(int, flag<N>, int R = read(0, flag<N + 1>{}))
{
    return R;
}

template <int N>
constexpr int read(float, flag<N>)
{
    return N;
}

template <int N = 0>
constexpr int counter(int R = write<read(0, flag<0>{}) + N>::value)
{
    return R;
}

E nós usamos isso como

static_assert(counter() != counter(), "Your compiler is mad at you"); 

template<int = counter()>
struct S {};

static_assert(!std::is_same_v<S<>, S<>>, "This is ridiculous");

Isto, a propósito, é uma contradição direta aos estados de armazenamento em metaprogramação em C ++?





c++17