可以创建任意类型的 constexpr 链表吗?

Can a constexpr linked list of arbitrary types be created?

我正在尝试实施基于特征的政策子系统,但我遇到了一个我真的不知道如何解决的问题(如果可能的话)。我有一个看起来像这样的特征:

template <typename ValueT, typename TagT = void, typename EnableT = void>
struct TPolicyTraits
{
    static void Apply(ValueT& value) { }
};

并且这个特性可以这样专门化:

struct MyPolicy {};

template <typename ValueT>
struct TPolicyTraits<ValueT, MyPolicy>
{
    static void Apply(ValueT& value) { /* Implementation */ }
};

我想在编译时在一种链表中注册策略。策略系统将像这样使用:

namespace PolicyTraits
{
    template <typename ValueT, typename TagT>
    using TPolicyTraitsOf = TPolicyTraits<std::decay_t<ValueT>, TagT>;

    template <typename ValueT>
    void Apply(ValueT&& value) 
    {
        // todo iterate through constexpr tag list and apply policies
    }

    template <typename TagT>
    constexpr void Enable()
    {
        // todo add tag to constexpr list
    }
}

int main()
{
    PolicyTraits::Enable<MyPolicy>();
    PolicyTraits::Apply(std::string());
}

有什么办法可以实现吗?

没有

constexpr 事物可能无法使用 new 分配内存。此限制最终可能会被删除。但就目前而言,情况就是这样。

这排除了使用任何动态大小的数据类型。

OTOH,constexpr 允许您相对容易地创建具有计算大小的静态大小的数据类型(假设可以在编译时完成计算)。这可能可以用来做你想做的事情。

除了在几个不同的编译单元中构建这样的类型同样不是可以完成的事情。并且该限制是 C++ compile/link 链所固有的,如果不对其进行重大更改将无法删除。

所以,不。

编译时元编程大部分是纯粹的。这意味着每个表达式的结果由其参数决定。

有一些例外情况可以通过使用参数相关的查找和友元函数以及 SFINAE 以相当疯狂的方式来解决。

不要那样做。

从政策中构建政策特征class,不要四处寻找全局状态。

TL;DR 在技术上是可行的,但这是一个糟糕的想法。别这样。

可能与您描述的问题相邻的问题有一个干净而优雅的解决方案。