2017-10-17 17 views
0

私はこのコードや意見を私がそれ以上考えているかどうかについてどのようにリファクタリングするかのアイデアを探しています。だから、boost :: variantを使用して一般的な戻り値の型を取得する

Pattern pattern; 

// do some stuff... 

// see if the pattern matches some data 
PatternVisitor pvisitor(dataBegin, dataEnd); 
if (boost::apply_visitor(pvisitor, pattern)) 
{ 
    // want to use pvisitor.matches generically inside here 
    // regardless of what variant pattern is 

    for (auto idx = 0; idx < pvisitor.matches.size(); idx) 
    { 
     // now use the match 
     std::string strMatch(pvisitor.matches[idx].first, pvisitor.matches[idx].second); 
     std::cout << strMatch << '\n'; 
    } 
} 

PatternVisitorを定義する方法:以下のboost::variant

using Pattern = boost::variant<std::regex, MyOwnClass>; 

を考えてみましょう今ここで私が何をしたいかのアイデアはありますか?私はstd::regex一部を実装して開始し、何かを思い付いた:MyOwnClassについて何...大丈夫だった

struct PatternVisitor : public boost::static_visitor<bool> 
{ 
    PatternVisitor(const char* sBegin, const char* sEnd) 
     : searchBegin(sBegin), searchEnd(sEnd) 
    { 
    } 

    bool operator()(const std::regex& regexp) 
    { 
     return std::regex_search(searchBegin, searchEnd, regmatches, regexp, std::regex_constants::match_continuous); 
    } 

    bool operator()(const MyOwnClass& myClass) 
    { 
     // save this implementation for later, return true for now 
     return true; 
    } 

    const char* searchBegin; 
    const char* searchEnd;  
    std::cmatch matches; 
}; 

けど?私の最初の考えは、私がstd::cmatch自分自身に住めることができるということでしたが、それは可能ではないようにもよいアイデアのようにも見えません。これは私が私が私が別のベクターにregmatchesから必要なデータをコピーしてることを好きではない動作しますが

struct PatternVisitor : public boost::static_visitor<bool> 
{ 
    PatternVisitor(const char* sBegin, const char* sEnd) 
     : searchBegin(sBegin), searchEnd(sEnd) 
    { 
    } 

    bool operator()(const std::regex& regexp) 
    { 
     std::cmatch regmatches; 
     if (std::regex_search(searchBegin, searchEnd, regmatches, regexp, std::regex_constants::match_continuous)) 
     { 
      for (const auto& m : regmatches) 
      { 
       matches.push_back(std::make_pair(m.first, m.second)); 
      } 
     } 

     return !matches.empty(); 
    } 

    bool operator()(const MyOwnClass& format) 
    { 
     // now I can just populate matches as needed 
     return true; 
    } 

    const char* searchBegin; 
    const char* searchEnd;  
    std::vector<std::pair<const char*, const char*>> matches; 
}; 

:だから、私は現在のソリューションは、このようなものです。

結果のマッチを一般的な方法で使用できるうちに、これをリファクタリングするにはどのような方法が良いでしょうか?

答えて

1

あなたのような何か、訪問者の内側にあなたの関数を適用することができる:

struct PatternVisitor : public boost::static_visitor<bool> 
{ 
    PatternVisitor(const char* sBegin, 
        const char* sEnd, 
        std::function<void (const char*, const char*)> f) 
     : searchBegin(sBegin), searchEnd(sEnd), f(f) 
    { 
    } 

    bool operator()(const std::regex& regexp) 
    { 
     std::cmatch regmatches; 
     if (std::regex_search(searchBegin, 
           searchEnd, 
           regmatches, 
           regexp, 
           std::regex_constants::match_continuous)) { 
      for (const auto& m : regmatches) { 
       f(m.first, m.second); 
      } 
      return true; 
     } 
     return false; 
    } 

    bool operator()(const MyOwnClass& myClass) 
    { 
     // save this implementation for later, return true for now 
     return true; 
    } 

    const char* searchBegin; 
    const char* searchEnd;  
    std::function<void (const char*, const char*)> f; 
}; 

そして

Pattern pattern = /*...*/; 
PatternVisitor pvisitor(dataBegin, dataEnd, [](const char* beg, const char* end) 
    { 
     std::string strMatch(beg, end); 
     std::cout << strMatch << '\n'; 
    }); 
boost::apply_visitor(pvisitor, pattern); 
+0

は早くこれをマークしている必要があります。これが私の実装を終えたものです。 – Addy

関連する問題