2017-10-17 6 views
0

이 코드 또는 의견을 내가 과도하게 생각하는지 여부를 리팩토링하는 방법에 대한 아이디어를 찾고 있습니다. 여기에 이제 다음 boost::variantboost :: 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 부분을 구현 시작과 같은 내놓았다 : 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을 채울 수 있지만 가능하지도 않거나 좋은 아이디어 인 것 같았다.

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