34
一个我已经幸运地遇到是constexpr counter,又名状态元编程。正如在帖子中提到的,它似乎在C++ 14下是合法的,我想知道C++ 17有什么变化吗?是有状态的元编程不健全(还)?我最亲爱的/邪恶的发明
以下是主要立足岗位
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?
如何'读(0,标志 {})'不会导致一个无限循环?文字0会导致它调用第一个重载('int'优先于'float'),这会自然地再次调用它。什么是终止条件? –
@NicolBolas通过SFINAE时,''的过载int'读(0,标志 {})'不能被称为对于足够大一些'N',因为我们还没有定义'adl_flag(标志)',因此,'浮动'重载将被调用。对于完整的解释,链接的文章写得很好。 –
还请注意David Krauss在相应的[std-discussion](https://groups.google.com/a/isocpp.org/d/msg/std-discussion/M6aJMH_ewoM/eAaBooYw-MsJ)线程中指出的缺陷,菲利普承诺在第四篇文章中谈到,但从未做过。 – Columbo