繁体   English   中英

这是使用 C++ 模板元编程的有效方法吗?

[英]Is this a valid way to use C++ Template Metaprogramming?

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

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

// 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");

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

考虑一个基于特征的设计:

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<int>存在。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM