有状态的元编程是病态的(还)吗?
Is stateful metaprogramming ill-formed (yet)?
我有幸遇到的最 beloved/evil 的发明之一是 constexpr counter,又名状态元编程。正如 post 中提到的,它在 C++14 下似乎是合法的,我想知道 C++17 有什么变化吗?
以下是主要基于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;
}
我们use it作为
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");
顺便说一下,这与 Storing States in C++ Metaprogramming?
直接矛盾
Defining a friend function in a template, then referencing that function later provides a means of capturing and retrieving metaprogramming state. This technique is arcane and should be made ill-formed.
Notes from the May, 2015 meeting:
CWG agreed that such techniques should be ill-formed, although the mechanism for prohibiting them is as yet undetermined.
这仍然是一个活跃的问题,C++17 至少目前不会有任何改变。虽然当确定了这样的禁止机制时,这可能会被追溯为DR。
我有幸遇到的最 beloved/evil 的发明之一是 constexpr counter,又名状态元编程。正如 post 中提到的,它在 C++14 下似乎是合法的,我想知道 C++17 有什么变化吗?
以下是主要基于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;
}
我们use it作为
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");
顺便说一下,这与 Storing States in C++ Metaprogramming?
直接矛盾Defining a friend function in a template, then referencing that function later provides a means of capturing and retrieving metaprogramming state. This technique is arcane and should be made ill-formed.
Notes from the May, 2015 meeting:
CWG agreed that such techniques should be ill-formed, although the mechanism for prohibiting them is as yet undetermined.
这仍然是一个活跃的问题,C++17 至少目前不会有任何改变。虽然当确定了这样的禁止机制时,这可能会被追溯为DR。