2017-10-17 75 views
0

我在尋找關於如何重構這段代碼或意見是否過度思考的想法。考慮以下boost::variant使用boost :: variant並得到一個通用的返回類型

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

現在這裏是想我做的想法:

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?我開始實施std::regex一部分,並想出了這樣的:

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; 
}; 

這是很好但是......約MyOwnClass什麼?我的第一個想法是我可以自己填充std::cmatch,但這似乎不可能,也不是一個好主意。因此,目前的解決方案我已經是這樣的:

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; 
}; 

雖然這工作我不喜歡說我抄襲,我從regmatches需要到其他載體的數據。

什麼是一個很好的方法來重構這個,而能夠以通用的方式使用結果匹配?

回答

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