C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
분야별 포럼
C++빌더
델파이
파이어몽키
C/C++
프리파스칼
파이어버드
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

자유게시판
세상 살아가는 이야기들을 나누는 사랑방입니다.
[28889] Re:C++ spaceship operator 연산자가 필요한 이유.
빌더(TWx) [builder] 3851 읽음    2021-03-14 09:46
C++공부중 님이 쓰신 글 :
: C++ 공부하던중 우주선 연산자가
: 왜필요한건지 모르겠습니다
: 그냥 비교 연산자로 되는거 아닌가요
:


답변:


spaceship operator 오버로드가 필요한 이유는... (Sorting에 목적이 있는 게 아님)

다른 언어와 비교해 보는 게 가장 쉽게 이해할 수 있을 것 같아
델파이 파스칼 언어를 예로 들어 보겠습니다.

다음과 같은 객체가 있다고 해 봅시다.

type
  TFoo = record
  public
    pStr: pAnsiChar;
end;

TFoo 객체의 pStr 스트링 리터럴 타입을 비교하는 평범한 방법은...

procedure foo;
var v1, v2 : TFoo;
begin
  v1.pStr := 'hello';
  v2.pStr := 'world';
 
  // Equal
  if CompareStr(v1.pStr,v2b.pStr) = 0 then...

  // LessThen
  if CompareStr(v1.pStr,v2b.pStr) < 0 then...

end;


위와 같은 식으로 프로그래밍 하는 방법일 겁니다.


그러나 간결하고 명확하게 프로그래밍 하기 위해선...
다음과 같이 비교 연산자 오퍼레이터를  이용할 필요가 있는데.

procedure foo;
var
  v1, v2: TFoo;
begin
  v1.pStr := 'hello';
  v2.pStr := 'world';

  if v1 = v2 then
  begin
    Memo1.Lines.Add(' == ');
  end;

  if v1 <> v2 then
  begin
    Memo1.Lines.Add(' <> ');
  end;

  if v1 > v2 then
  begin
    Memo1.Lines.Add(' > ');
  end;

  if v1 >= v2 then
  begin
    Memo1.Lines.Add(' >= ');
  end;

  if v1 < v2 then
  begin
    Memo1.Lines.Add(' < ');
  end;

  if v1 <= v2 then
  begin
    Memo1.Lines.Add(' <= ');
  end;
end;


위의 조건을 모두 만족하도록 델파이 파스칼로 프로그래밍 할려면...

다음과 같이 6개의 비교 연산자를 모두 오버로드 해서 일일히 구현해야 합니다.

// 델파이 파스칼은 클래스에서 비교 연산자를 오버로드 하는 게 불가능 함.
// 그래서 class 대신 record를 이용.
 type
  TFoo = record
  public
    pStr: pAnsiChar;
    class operator GreaterThan(a, b: TFoo): Boolean;
    class operator GreaterThanOrEqual(a, b: TFoo): Boolean;
    class operator LessThan(a, b: TFoo): Boolean;
    class operator LessThanOrEqual(a, b: TFoo): Boolean;
    class operator Equal(a, b: TFoo): Boolean;
    class operator NotEqual(a, b: TFoo): Boolean;
  end;

class operator TFoo.GreaterThan(a, b: TFoo): Boolean;
begin
  Result := False;
  if CompareStr(a.pStr, b.pStr) > 0 then
    Exit(True);
end;

class operator TFoo.GreaterThanOrEqual(a, b: TFoo): Boolean;
begin
  Result := False;
  if CompareStr(a.pStr, b.pStr) >= 0 then
    Exit(True);
end;

class operator TFoo.LessThan(a, b: TFoo): Boolean;
begin
  Result := False;
  if CompareStr(a.pStr, b.pStr) < 0 then
    Exit(True);
end;

class operator TFoo.LessThanOrEqual(a, b: TFoo): Boolean;
begin
  Result := False;
  if CompareStr(a.pStr, b.pStr) <= 0 then
    Exit(True);
end;

class operator TFoo.Equal(a, b: TFoo): Boolean;
begin
  Result := False;
  if CompareStr(a.pStr, b.pStr) = 0 then
    Exit(True);
end;

class operator TFoo.NotEqual(a, b: TFoo): Boolean;
begin
  Result := False;
  if CompareStr(a.pStr, b.pStr) <> 0 then
    Exit(True);
end;



위와 같이...
델파이 파스칼로 구현할려면...
조건을 만족하도록 6개의 비교 연산자 전부를 일일히 구현해야 하지만...


C++ spaceship operator를 이용하면...

다음과 같이 단 2개의 오버로드만으로 모든 조건을 만족하도록 간단하게 구현할 수 있지요.

class CFoo
{
public:
  const char* s;
  auto operator==(const CFoo& r) const { return !strcmp(s, r.s); }
  auto operator<=>(const CFoo& r) const { return strcmp(s, r.s); } // spaceship operator
};


굉장히 간단하죠.

위의 경우엔 스트링 리터럴 타입을 비교하기 위해 strcmp() 함수를 이용해서
2개의 오퍼레이터를 오버로드 한 케이스 이지만...


비교할 대상이 다음과 같은 스칼라 타입이면 오퍼레이터 오버로드 구현 조차도 필요없게 됍니다

class CFoo2
{
public:
  int k;
  auto operator<=>(const CFoo2&) const = default; // spaceship operator
};


컴파일러로 하여금 디폴트 spaceship operator 오버로드 코드를 생성하도록 지시하면 그만이죠.

spaceship operator는 Sorting에 목적이 있는 게 아님.
Sorting은 람다로 간단하게 처리할 수 있으므로.


이와 같이 C++20에서 도입된 spaceship operator '<=>'를 이용하면
코드를 굉장히 간단하게 구현할 수 있지요. 컴파일러에 의해서 코드 옵티마이징이 드라이브 걸릴 때도 훨씬 유리하고


그런데...

엠바 컴파일러는 C++20을 지원하지 않음.


양병규 [bkyang]   2021-03-14 14:28 X
아~~ 그렇군!!
이라고.. 생각하고 넘어갔을 텐데요.
"Sorting에 목적이 있는 게 아님"이라고 굳이 안 하셨다면요.

뭔지는 잘 모르지만
말씀하신 그런 식일 것 같은데 길게 설명하면 대부분 안 읽기 때문에 바로 예를 든 건데요. 제 말의 요지는 소트가 아니라 "if 문과 연산자를 여러번 쓰는 걸 짧게 줄이는 용도가 아닐까요?" 라고 한 겁니다. 그것도 틀린 표현이라면 제가 잘못했습니다.

+ -

관련 글 리스트
28888 C++ 우주선 연산자가 왜 필요한가요 C++공부중 2577 2021/03/13
28889     Re:C++ spaceship operator 연산자가 필요한 이유. 빌더(TWx) 3851 2021/03/14
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.