C++에서 vs typedef 사용

Jay Shaw 2023년10월12일
  1. C++에서 using 키워드
  2. C++의 typedef 키워드
  3. 템플릿 정의에서 typedefusing 사용
  4. 결론
C++에서 vs typedef 사용

이 기사에서는 typedefusing을 구분하려고 합니다. C++ 함수형 프로그래밍에서 이러한 키워드는 동일한 목적과 의미를 가지므로 그들 사이에 매우 좁은 차이가 있습니다.

이 문서에서는 독자가 이러한 키워드의 기능과 typedefusing의 차이점을 이해할 수 있도록 다양한 컨텍스트에서 키워드를 설명합니다.

C++에서 using 키워드

typedef와 대조되는 using 키워드를 이해하는 것은 typedefusing의 차이점을 배우는 데 중요합니다.

객체를 프로그램의 현재 범위로 가져오는 데 사용됩니다. 이는 C++에서 지정자를 가져오는 액세스 도구로 사용할 수 있음을 의미합니다.

예를 들어 보겠습니다.

#include <iostream>

int main() {
  using std::cout;
  using std::string;

  int a = 56;
  cout << a;
  return 0;
}

출력:

56

여기서 using 키워드는 네임스페이스에서 coutstring과 같은 지정자를 액세스하고 프로그램 범위 내로 가져오는 데 사용됩니다.

마찬가지로 using을 사용하여 다른 지정자에 액세스하거나 using namespace as std를 사용하여 전체 네임스페이스를 가져올 수도 있습니다. 이렇게 하면 프로그램의 범위 내에서 전체 네임스페이스를 가져오고 모든 지정자는 std를 사용하여 액세스할 수 있습니다.

using 키워드의 예

아래의 코드 스니펫은 두 개의 정수 변수 ab를 매개변수로 갖는 공용 메소드 add를 사용하여 Parent 클래스를 생성합니다. add 메소드는 두 변수의 합계를 인쇄합니다.

자식 클래스는 보호 모드에서 부모 클래스를 파생합니다. 즉, 부모 클래스의 모든 구성원이 보호된 구성원으로 상속됩니다.

main 함수 내에서 Child 클래스를 사용하여 개체의 인스턴스가 생성되고 해당 개체를 사용하여 add 메서드가 파생됩니다.

#include <iostream>
using namespace std;
class Parent {
 public:
  void add(int a, int b) { cout << "Result = " << a + b << endl; }
};
class Child : protected Parent {
 public:
  using Parent::add;
};
int main() {
  Child obj;
  obj.add(15, 30);
  return 0;
}

출력:

Result = 45

여기서 using 키워드는 Child 클래스를 통해 Parent 클래스에서 add 메서드에 액세스하는 데 사용됩니다.

C++에서 using 키워드로 루프 구현

여기서 구문은 using을 통해 for 루프를 구현합니다.

for (using i = int; i{} != 0;) {
  i++;
}

범위 기반 루프의 경우 using은 다음과 같이 사용됩니다.

std::vector<int> v{1, 2, 3};
for (using Foo = int; Foo f : v) {
  (void)f;
}

C++에서 using 키워드가 있는 Switch Case

switch case 문에서 using은 다음과 같이 구현됩니다.

if (using Foo = int; true) {
  (void)Foo{};
}
switch (using Foo = int; 0) {
  case 0:
    (void)Foo{};
}

C++의 typedef 키워드

typedef 키워드에는 사용자 지정 이름을 사용하여 유형의 이름을 지정하는 기능이 있습니다. 이는 기존 데이터 유형에 대해 별명을 도입할 수 있음을 의미합니다.

typedefusing의 주요 차이점은 이 섹션에서 확인할 수 있습니다.

아래 프로그램은 이 개념을 명확하게 설명합니다.

#include <stdio.h>
#include <string.h>

typedef struct Books {
  char title[50];
  char author[50];
  char subject[100];
  int book_id;
} Book;

4개의 변수가 있는 struct 클래스 Book이 도입되었습니다. 이 4개의 변수는 typedef를 사용하여 새로운 데이터 유형으로 구조화되며 이 유형에는 Book이라는 이름이 지정됩니다.

main 클래스 내에서 Book 유형에 액세스하고 해당 변수를 가져오려면 새 개체를 만들어야 합니다(요구 사항에 따라).

object_name.variable_name,"input" 구문을 사용하여 개별 변수가 호출되는 것을 관찰할 수 있습니다. 이러한 변수에 데이터가 제공되면 이를 호출하는 데 사용된 것과 동일한 방법을 사용하여 인쇄됩니다.

int main() {
  Book book;

  strcpy(book.title, "Typedef vs using");
  strcpy(book.author, "JS");
  strcpy(book.subject, "C Programming");
  book.book_id = 6495407;

  printf("Book title : %s\n", book.title);
  printf("Book author : %s\n", book.author);
  printf("Book subject : %s\n", book.subject);
  printf("Book book_id : %d\n", book.book_id);

  return 0;
}

출력:

Book title : Typedef vs using
Book author : JS
Book subject : C Programming
Book book_id : 6495407

C++에서 typedef 키워드를 사용하는 루프

루프 반복 중에 typedeffor (typedef (datatype)Function; Function{} != 0;) 구문을 사용하여 정의됩니다.

for (typedef int i; i{} != 0;) {
  i++;
}

범위 기반 루프 반복 중에 typedef는 다음과 같이 사용됩니다.

std::vector<int> v{1, 2, 3};
for (typedef int Foo; Foo f : v)
//   ^^^^^^^^^^^^^^^ init-statement
{
  (void)f;
}

2차원 행렬 내부의 범위 기반 루프의 또 다른 예:

for (typedef struct {
       int x;
       int y;
     } P;
     auto [x, y] : {P{1, 1}, {1, 2}, {3, 5}}) {
  (void)x;
  (void)y;
}

C++에서 typedef 키워드를 사용하는 Switch Case

typedef 키워드는 아래와 같이 switch case 문에서 사용됩니다.

if (typedef int Foo; true) {
  (void)Foo{};
}

switch (typedef int Foo; 0) {
  case 0:
    (void)Foo{};
}

템플릿 정의에서 typedefusing 사용

우리는 함수형 프로그래밍의 맥락에서 typedefusing의 차이점을 관찰했습니다. 이해해야 할 또 다른 중요한 부분은 템플릿을 정의하는 방법입니다.

C++에서 typedefs에는 템플릿의 별칭을 정의하는 기능이 있습니다. 매우 오랫동안 사용되어 왔지만 typedef의 의미 체계가 템플릿과 잘 어울리지 않는다는 것이 관찰되었습니다.

이 문제를 해결하기 위해 typedef가 감가상각되었으며 using이 발생했습니다.

아래 예에서는 템플릿 정의와 관련하여 typedefusing의 차이점에 대해 설명합니다.

C++에서 typedef를 사용한 앨리어싱 템플릿

예 1:

여기에서 사각형은 x 길이와 템플릿을 사용하여 별칭을 지정해야 하는 정적 너비를 갖는 것으로 정의되었습니다.

<size_t N>은 직사각형의 길이를 저장하는 템플릿입니다. 반대로 Dimensiontypedef를 사용하여 Rectangle이라는 별칭이 지정되는 개체입니다.

여기에서 코드는 RectangleDimension<N,1>의 별칭으로 지정합니다. 즉, Dimension 개체는 길이와 너비를 갖게 됩니다. 여기서 Dimension 개체의 길이는 <size_t N>이고 너비는 1입니다.

template <size_t N>
struct Rectangle {
  typedef Dimension<N, 1> type;
};

이는 프로그래머가 size_t N이라는 단일 값 매개변수를 Rectangle에 전달해야 함을 의미합니다. 컴파일러는 전달된 값을 길이로 받아들이고 너비는 1로 설정합니다.

Rectangle<5>::int 구문은 정수 값 5를 개체 Dimension에 전달하며 Dimension<5,1>을 쓰는 것과 동일합니다.

위의 예제는 typedef가 감가 상각되므로 최근 C++ 버전에서 더 이상 사용되지 않습니다. 템플릿에 별칭을 부여하기 위해 using을 사용하는 것은 위의 예보다 간단합니다.

예 2:

템플릿 클래스 Match는 아래 코드 스니펫에 정의되어 있습니다. 이 Match 클래스에는 별칭 템플릿 MatchBox가 제공됩니다.

Match 클래스는 향후에도 대체될 수 있습니다.

template <typename U>
struct Match {};

template <typename U>
struct MatchBox {
  typedef Match<U> type;
};

MatchBox<int>::type variable;

template <typename V>
struct bar {
  typename MatchBox<V>::type_var_member;
}

형식 추상화가 필요하지만 템플릿 매개 변수도 보존하여 향후 제공될 수 있도록 해야 하는 경우 작성해야 하는 코드입니다.

C++에서 using 키워드로 템플릿 앨리어싱

예 1:

이 섹션에서는 템플릿 컨텍스트에서 typedefusing의 차이점을 설명합니다. 여기에서 템플릿 <size_t N>은 사각형의 길이를 저장하는 typedef 예제 1에서 사용된 것과 동일합니다.

struct를 사용하는 대신 using 키워드를 통해 Rectangle 별칭이 Dimension 개체에 할당됩니다. 이는 오퍼레이터를 할당하는 것과 동일한 방식으로 수행됩니다.

별칭 할당 후 별칭 Rectangle은 각각 길이와 너비로 N1을 가집니다.

template <size_t N>
using Rectangle = Dimension<N, 1>;

using은 작성 및 구현이 더 쉬운 보다 세련된 버전의 앨리어싱을 제공한다는 것을 알 수 있습니다. 여기에 사용된 구문의 가독성은 이제 기존의 변수 및 연산자 할당과 비슷하기 때문에 개선된 것 같습니다.

예 2:

이 예에서는 템플릿 매개 변수를 계속 열어 두어 지정이 가능하도록 합니다. typedef 예에서 이 프로세스에는 여러 줄의 코드가 필요했습니다. 그러나 using 구문은 코드와 복잡성을 줄입니다.

template <typename U>
using MatchBox = Match < U

                             MatchBox<int>
                                 variable;
template <typename V>
struct bar {
  MatchBox<V> _var_member;
}

프로세스가 변수 복사 할당과 유사하기 때문에 using 키워드를 사용하여 템플릿의 별칭을 정의하는 것이 typedef보다 훨씬 쉽습니다.

결론

이 기사에서는 C++에서 typedef 키워드와 using 키워드의 차이점에 대해 설명합니다. 독자는 이러한 키워드의 기본적인 차이점과 다양한 프로그래밍 컨텍스트에서의 구현을 이해할 것입니다.

이 기사가 학습 여정에 도움이 되었기를 바랍니다.