2017-11-15 6 views
3

テンプレートを使用するC++のメソッドfindIDがあります。このメソッドでは、入力タイプに基づいて条件を実行できます。テンプレートパラメータUは、int型またはstring型のいずれかになります。私はIDのタイプに基づいて別の条件を実行したい。変数が文字列かどうかをテストするC++の条件文

私が持っているコードにされては、次のとおりです。

template <typename S> 
template <typename U> 
S * findID(U ID){ 
    for (typename vector<S*>::collectionsIter element = collection.begin() ; element != collection.end(); ++element) 
     if((*element)->getID() == ID) return *element; 
    return NULL; 
} 

私は私のコードは次の操作を実行したい:

template <typename S> 
    template <typename U> 
    S * findID(U ID){ 

     ***if ID is an int: 
     for (typename vector<S*>::collectionsIter element = collection.begin() ; element != collection.end(); ++element) 
      if((*element)->getID() == ID) return *element; 


     ***if ID is a string: 

     for (typename vector<S*>::collectionsIter element = collection.begin() ; element != collection.end(); ++element) 
      if((*element)->getStringID() == ID) return *element; 

     ***else 

     return NULL; 


    } 

私のことができるようにしたいので、私はこれをしたい理由がありますIDの文字列変数をgetStringID()の文字列メソッドと比較し、IDのint変数をgetID()のintメソッドに比較します。さらに、これらのメソッドを別々のメソッドに分割したくないので、テンプレートとこれらの条件を使用してメソッドを1つのメソッドにリファクタリングしようとしています。ここで

+1

を何がしたいことは、 "テンプレートの部分特殊化" と呼ばれています。あなたの好きなC++リファレンスでそれを探してください。あなたの道を見つけるでしょう。 –

+0

「コレクション」から来た場所はどこですか? – Jarod42

+0

コレクションは、コレクションクラスに格納されたベクトルのプライベートメンバーです。 – MastRofDsastR

答えて

3

わずか2つのオーバーロードを使用します。

template <typename S> 
S* findID(int ID){ 
    for (auto* element : collection) 
     if (element->getID() == ID) return element; 
    return nullptr; 
} 

template <typename S> 
S* findID(const std::string& ID){ 
    for (auto* element : collection) 
     if (element->getStringID() == ID) return element; 
    return nullptr; 
} 
1

はC++ 17 if constexprを使用して、それを行うための一つの方法です:

struct Foo { 
    int id; 
    std::string stringId; 

    int getId() const { return id; } 
    const std::string& getStringId() const { return stringId; } 
}; 

template <typename Cont, typename T> 
auto findId(const Cont& c, const T& id) { 
    const auto pred = [&id](const auto& x) { 
     if constexpr (std::is_convertible_v<T, std::string>) 
      return x.getStringId() == id; 
     else if constexpr (std::is_convertible_v<T, int>) 
      return x.getId() == id; 
     else 
      static_assert(false, "Unsupported id type."); 
     return false; 
    }; 
    const auto findIt = std::find_if(begin(c), end(c), pred); 
    return findIt == end(c) ? nullptr : &(*findIt); 
} 

int main() { 
    using namespace std; 
    vector<Foo> foos{{1, "1"}, {2, "2"}, {3, "3"}}; 
    auto foo2Int = findId(foos, 2); 
    auto foo2String = findId(foos, "2"s); 
    cout << foo2Int->id << ", " << foo2String->stringId << '\n'; 
} 
関連する問題