【问题标题】:Is this a valid way to use C++ Template Metaprogramming?这是使用 C++ 模板元编程的有效方法吗?
【发布时间】:2021-05-20 02:49:34
【问题描述】:

我正在尝试使用模板,并且遇到了类似这样的代码。调用模板化方法并显式传递结构作为模板参数的代码。该结构包含有关如何使用输入类型的所有特定逻辑。

我想知道这是否是使用 C++ 模板的有效方式,或者这是一团糟,应该通过类继承来完成?我找不到像这样使用模板的任何示例,所以我觉得有更好的方法

// Template parameter that holds all the logic for a specific input type
// Similar structs would exist for double, string, etc. In my code these would be classes not primitives
struct HowToHandleIntType {
  using Type = int;

  struct Add {
    int Run(int a, int b) { return a+b; }
  };

  struct Remove {
    void PreRemove(int a) {
      // Do Something to a
    }
    bool Run(int a) {
      // Do Something to a
    }
  }
};

// Generic methods that call into the template struct for all real logic
template <typename HowToHandle>
int add(typename HowToHandle::Type a, typename HowToHandle::Type b) {
  return HowToHandle::Add::Run(a, b);
}

template <typename HowToHandle>
bool remove(typename HowToHandle::Type a) {
  HowToHandle::Remove::PreRemove(a);
  return HowToHandle::Remove::Run(a);
}

// This is how the methods would be used 
add<HowToHandleIntType>(5, 8);
add<HowToHandleDoubleType>(5.0, 8.0);
remove<HowToHandleStringType>("bob");

【问题讨论】:

  • 这听起来很像基于策略的设计。不过,可能会有更好的设计。
  • 谢谢,基于策略的设计看起来确实很相似。在基于策略的设计中,模板参数似乎用于以某种方式修改类。在我的情况下,我没有类,只有一个操作列表,如添加、删除等,用户可以使用它们,只要它们传入正确的 HowToHandle struct

标签: c++ templates template-meta-programming


【解决方案1】:

这绝对是有效,而且通常不是一个糟糕的设计。但也许它失去了它应该具有的类型推断的能力。

考虑一个设计,基于特征

template<typename T>
struct HowToHandleThisType;

template<>
struct HowToHandleThisType<int>{
    typedef int Type;
    struct Add{
        // ...
    };
    struct Remove{
        // ...
    };
};

template<typename T, typename Trait = HowToHandleThisType<T>, typename = typename Trait::Type /* SFINAE */>
typename Trait::Type add(T a, T b){
    return Trait::Add::Run(a, b);
}

int main(){
    auto x = add(1, 2); // T = int
}

在这种情况下,您无需显式提供HowToHandleIntType 作为模板参数。甚至用户实际上可能不知道特征 HowToHandleThisType&lt;int&gt; 存在。

但有时我们可能想要或必须分配其中一个特征来执行此操作,例如 add&lt;int, HowToHandleThisType&lt;int&gt;&gt;(1, 2)(我们总是提供另一个重载以使 add&lt;HowToHandleThisType&lt;int&gt;&gt;(1, 2) 有效),它等于您的设计。

【讨论】:

    猜你喜欢
    • 2012-01-06
    • 2012-07-12
    • 1970-01-01
    • 1970-01-01
    • 2021-02-22
    • 1970-01-01
    • 2013-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多