programing tip

'tuple'과 'tie'를 통해 비교 연산자를 구현하는 것이 좋습니다.

itbloger 2020. 8. 31. 07:31
반응형

'tuple'과 'tie'를 통해 비교 연산자를 구현하는 것이 좋습니다.


(참고 : tuple그리고 tieBoost 또는 C ++ 11에서 가져올 수 있습니다.)
두 개의 요소 만있는 작은 구조체를 작성할 때 strict-weak-ordering std::pair과 같이 해당 데이터 유형에 대해 모든 중요한 작업이 이미 수행 되었기 때문에를 선택하는 경향이 있습니다. operator<.
단점은 거의 쓸모없는 변수 이름입니다. 나 자신이 그 창조하더라도 typedef, 나는 2 일 후 기억하지 않습니다 first어떤 second그들은 동일한 유형의 모두, 특히이었다 정확하게. 중첩 pairs가 상당히 짜증나 기 때문에 두 개 이상의 구성원의 경우 더욱 악화됩니다 .
다른 옵션은tuple, Boost 또는 C ++ 11에서 왔지만 실제로 더 멋지고 명확하게 보이지는 않습니다. 그래서 필자는 필요한 비교 연산자를 포함하여 직접 구조체 작성으로 돌아갑니다.
특히는 operator<매우 번거로울 수 있으므로 다음에 대해 정의 된 작업에 의존하여이 모든 혼란을 피할 수 있다고 생각했습니다 tuple.

예를 operator<들어 strict-weak-ordering의 경우 :

bool operator<(MyStruct const& lhs, MyStruct const& rhs){
  return std::tie(lhs.one_member, lhs.another, lhs.yet_more) <
         std::tie(rhs.one_member, rhs.another, rhs.yet_more);
}

( tietupleT&전달 인자에서 참조.)


편집 : @DeadMG가 개인적으로 상속하라는 제안은 tuple나쁜 것은 아니지만 몇 가지 단점이 있습니다.

  • 운영자가 독립적 인 경우 (아마도 친구 일 수 있음) 공개적으로 상속해야합니다.
  • 캐스팅을 사용하면 내 함수 / 연산자 ( operator=특히)를 쉽게 우회 할 수 있습니다.
  • 으로 tie그들이 순서에 대한 문제가되지 않는 경우 솔루션, 나는 특정 회원을 남길 수 있습니다

이 구현에 고려해야 할 단점이 있습니까?


이것은 확실히 직접 굴리는 것보다 올바른 연산자를 작성하는 것을 더 쉽게 만들 것입니다. 프로파일 링이 비교 작업이 애플리케이션의 시간 소모적 인 부분임을 보여주는 경우에만 다른 접근 방식을 고려한다고 말하고 싶습니다. 그렇지 않으면 유지 관리의 용이성이 성능 문제보다 중요합니다.


나는이 같은 문제를 건너 왔고 내 솔루션은 c ++ 11 가변 템플릿을 사용합니다. 다음은 코드입니다.

.h 부분 :

/***
 * Generic lexicographical less than comparator written with variadic templates
 * Usage:
 *   pass a list of arguments with the same type pair-wise, for intance
 *   lexiLessthan(3, 4, true, false, "hello", "world");
 */
bool lexiLessthan();

template<typename T, typename... Args>
bool lexiLessthan(const T &first, const T &second, Args... rest)
{
  if (first != second)
  {
    return first < second;
  }
  else
  {
    return lexiLessthan(rest...);
  }
}

인수가없는 기본 케이스에 대한 .cpp :

bool lexiLessthan()
{
  return false;
}

이제 귀하의 예는 다음과 같습니다.

return lexiLessthan(
    lhs.one_member, rhs.one_member, 
    lhs.another, rhs.another, 
    lhs.yet_more, rhs.yet_more
);

In my opinion, you're still not addressing the same issue as the std::tuple solves- namely, you have to know both how many and the name of each member variable, you're duplicating it twice in the function. You could opt for private inheritance.

struct somestruct : private std::tuple<...> {
    T& GetSomeVariable() { ... }
    // etc
};

This approach is a little bit more of a mess to begin with, but you're only maintaining the variables and names in one place, instead of in every place for every operator you wish to overload.


If you plan to use more than one operator overload, or more methods from tuple, I'd recommend making tuple a member of the class or derive from tuple. Otherwise, what you're doing is a lot more work. When deciding between the two, an important question to answer is: Do you want your class to be a tuple? If not I would recommend containing a tuple and limiting the interface by using delegation.

You could create accessors to "rename" the members of the tuple.

참고URL : https://stackoverflow.com/questions/6218812/implementing-comparison-operators-via-tuple-and-tie-a-good-idea

반응형