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

标签 c++ c++11 traits constexpr

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

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());
}

有什么办法可以实现吗?

最佳答案

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

有些异常可以通过使用参数依赖查找和友元函数以及 SFINAE 以相当疯狂的方式绕过它。

不要那样做。

从其策略构建策略特征类,不要四处寻找全局状态。

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

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

关于c++ - 可以创建任意类型的 constexpr 链表吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57294730/

相关文章:

rust - `<T: Trait>` 和 `where T: Trait` 有什么区别?

c++ - 内联模板特化

c++ - 如果我不执行 const_cast<char*> 并仅使用 ( char * ) 类型转换,会有什么危害吗?

c++ - 转发声明 opengl 类型

arrays - [_; 中的数组长度 N 允许使用什么表达式? N]?

php trait 使用另一个 trait

c++ - std::getline 不接受 std::back_insert_iterator

c++ - 如果派生类具有私有(private)变量,则派生类数组不起作用

c++ - GCC w/inline assembly & -Ofast 为内存操作数生成额外代码

c++ - boost::bind() 创建参数的许多拷贝