2016-12-20 6 views
2

自分のためにコマンドラインパーサーを操作する。私はこのコンストラクトに問題があり、誰かが回避策を提案することを期待していることをすぐに知っていました。異なる/未知の種類のクラステンプレートを持つベクトルを初期化する

さまざまな種類のデータを含む可能性のあるvectorにパラメータの引数リスト(テンプレートに基づく)を格納します。しかし私の理解から、vector<template<type>>を静的に定義する必要があります。複数の型を除く方法がありますか?ここで

は、私が何を意味するかの例です:あなたがC++ 11のソリューションを受け入れることができる場合

#include <vector> 
#include <memory> 

namespace clparser 
{ 
    class CommandLine { 
    private: 
     std::vector<Parameter<AnyType??>*> ArgumentList; 

    public: 

     void Add(Parameter<AnyType??>* Parameter) { ArgumentList.push_back(Parameter); } 
    }; 


    template<typename T> 
    class Parameter { 
    private: 
     const char *ShortOption; 
     const char *LongOption; 
     const char *Description; 
     const bool RequiredField; 
     const char *DefaultValue; 


    public: 
     Parameter(const char *ShortOption, const char *LongOption, const char *Description, const bool RequiredField, const char *DefaultValue) 
      : ShortOption(ShortOption), LongOption(LongOption), Description(Description), RequiredField(RequiredField), DefaultValue(DefaultValue) 
     { 

     } 
    }; 
} 
+1

'boost :: any'ですか? –

+0

私はブーストの依存関係がない方が好きですが、STLでこれを達成できない場合は...ありがとうございます。 – user0000001

+0

C++ 17 'any'も' std'でも利用可能ですので –

答えて

0

、私はあなたに私のコマンドラインパーサからIPER-簡易版を提案します。あなたにインスピレーションを与えることができる願望。

私の解決策の背後にある考え方は、ベース/派生多型の使用です:純粋な仮想class optBaseは、オプション専用のテンプレートクラスのセットのベースです(次の例では、class optのみですが、私のパーサー)。その後

(ないテンプレート)class yDatastd::unique_ptr<optBase>が含まれている(;しかし、私はC++ 11以降の使用をお勧めしますがoptBaseへの単純なポインタを使用する場合は、あまりにもC++ 98でコンパイルすることができ、私は考えます)。

class yDataはおおよそあなたのclass Parameterに対応しますが(ここではトリックです)テンプレートクラスではありません。テンプレートクラスへの基本ポインタを含みます。

私のはclass clparserに、std::map<int, yData> idMapは(おおよそ)std::vector<Parameter<AnyType??>*> ArgumentListに対応しています。

idMapをフィードするために、私はテンプレートメソッドのセットを作成しました(optbaseクラスから派生したものごとに1つ)。次の例では、それらのうちの1つを半正規化したバージョンが表示されます:addOpt()(おおよそ、Add()に対応)。

次の例では、addOpt()の用途のカップルと少しmain()を見ることができます:intパラメータの最初とdoubleパラメータ(私の解決策の重要な(と弱点)のための第二:返された値は、参照変数に保存する必要があります。単純変数ではありません。

#include <map> 
#include <memory> 


    class optBase 
    { 
     public: 
     // some pure virtual methods 
    }; 

    template <typename X> 
    class opt : public optBase 
    { 
     private: 
     X val { }; 
     // ... 

     public: 

     opt() 
      { } 

     opt (X const & v0) 
      : val { v0 } // ... 
      { } 

     X const & getVal() const 
      { return val; } 

     X & getVal() 
      { return val; } 

     // ... 
    }; 

    // other optBase derived classes (for flags, containers of values, etc) 

    class yData 
    { 
     private: 
     // ... 
     std::unique_ptr<optBase> optB; 

     public: 
     yData (/* other arguments */ std::unique_ptr<optBase> optB0) 
      : /* something else */ optB { std::move(optB0) } 
      { } 
     // ... 
     std::unique_ptr<optBase> const & getPnt() const 
      { return optB; } 
    }; 

    class yarg 
    { 
     private: 
     // ... 
     std::map<int, yData> idMap; 
     // ... 

     public: 
     // ... 
     template <typename T> 
     T & addOpt (/* other arguments */ T const & def = T()) 
      { 
      int  id { /* some value */ }; 
      opt<T> * optP { nullptr }; 
      // ...& 
      idMap.emplace(std::piecewise_construct, 
        std::forward_as_tuple(id), 
        std::forward_as_tuple(/* other arguments */ 
        std::unique_ptr<optBase>(optP = new opt<T>(def)))); 

      return optP->getVal(); 
      } 

    }; 

int main() 
{ 
    yarg y; 

    // important: use a *reference* 
    auto & pi = y.addOpt(3); // pi is a int 
    auto & pd = y.addOpt(3.0); // pd is a double 

    static_assert(std::is_same<decltype(pi), int &>::value, "!"); 
    static_assert(std::is_same<decltype(pd), double &>::value, "!!"); 
} 
関連する問題