簡體   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