C ++ 11에서 'typedef'와 'using'의 차이점은 무엇입니까?


905

C ++ 11에서 s using와 같은 유형 별칭을 쓰는 데 사용할 수 있음을 알고 있습니다 typedef.

typedef int MyInt;

내가 이해 한 것에서 다음과 같습니다.

using MyInt = int;

그리고 새로운 구문은 " template typedef" 을 표현하는 방법을 찾기위한 노력에서 나왔습니다 .

template< class T > using MyType = AnotherType< T, MyAllocatorType >;

그러나 처음 두 개의 비 템플릿 예제에서 표준에 다른 미묘한 차이점이 있습니까? 예를 들어, typedef"약한"방식으로 앨리어싱을 수행합니다. 즉, 새 유형을 작성하지 않고 새 이름 만 작성합니다 (해당 이름 사이에 변환이 내재되어 있음).

동일 using하거나 새로운 유형을 생성합니까? 차이점이 있습니까?


215
나는 개인적으로 새로운 구문을 선호한다. 왜냐하면 새로운 변수는 규칙적인 변수 할당과 훨씬 유사하여 가독성을 향상시킨다. 예를 들어, typedef void (&MyFunc)(int,int);또는 을 선호 using MyFunc = void(int,int);합니까?
Matthieu M.

13
나는 완전히 새로운 구문을 사용한다고 전적으로 동의합니다. 그것이 실제로 차이가 없는지 확인하기 위해 내가 묻는 이유입니다.
클라 임

80
@MatthieuM. 그 둘은 다른 btw입니다. 그것은 typedef void MyFunc(int,int);(실제로 나쁘게 보이지 않음), 또는using MyFunc = void(&)(int,int);
R. Martinho Fernandes

5
@ R.MartinhoFernandes가 왜 필요합니까 (&) 에서와 using MyFunc = void(&)(int,int);? MyFunc함수에 대한 참조 라는 의미 입니까? & 를 생략하면 어떻게됩니까?
Rich

7
예, 함수 참조입니다. 와 같습니다 typedef void (&MyFunc)(int,int);. 당신은 생략 한 경우 &는 동등의typedef void MyFunc(int,int);
R. 마르틴 페르난데스

답변:


584

표준 (강조 광산) (7.1.3.2)과 동일합니다.

별칭 정의로 typedef-name을 도입 할 수도 있습니다. using 키워드 뒤에 오는 식별자는 typedef-name이되고 식별자 뒤에 오는 선택적 attribute-specifier-seq는 해당 typedef-name에 적용됩니다. typedef 지정자가 도입 한 것과 동일한 의미를 갖습니다. 특히 새 유형을 정의하지 않으며 type-id에 나타나지 않아야합니다.


24
대답에서 using키워드는의 상위 집합 인 것 같습니다 typedef. 그러면 typdef앞으로 더 이상 사용되지 않습니까?
iammilind

49
사용 중단이 반드시 제거하려는 의도를 나타내는 것은 아닙니다. 단지 다른 수단을 선호하는 것이 좋습니다.
Iron Savior

18
그러나 왜 그들이 typedef를 템플릿으로 만들 수 없었는지 궁금합니다. 시맨틱이 템플릿에서 제대로 작동하지 using않았기 때문에 구문을 정확하게 소개 한 곳을 읽은 것을 기억 합니다 typedef. 이는 using정확히 동일한 의미를 갖도록 정의 된 사실과 모순 됩니다.
celtschk

12
@celtschk : 제안에서 그 이유에 대해 이야기합니다 n1489. 템플릿 별명은 하지 유형에 대한 별칭 있지만, 템플릿 그룹에 대한 별칭. typedef펠트를 구별하려면 새로운 구문이 필요합니다. 또한 OP의 질문은 템플릿이 아닌 버전의 차이점에 대한 것입니다.
Jesse Good

4
그렇다면 왜이 중복성이 도입 되었습니까? 동일한 목적을위한 2 가지 구문. 그리고 나는 typdef더 이상 사용되지 않는 것을 보지 못했습니다 .
Benoît

237

다음을 제외하고는 거의 동일합니다.

별칭 선언은 템플릿과 호환되지만 C 스타일 typedef는 호환되지 않습니다.


29
특히 대답의 단순함을 좋아하고 조판의 기원을 지적합니다.
g24l

1
@ g24l 당신은 typedef를 의미합니다 ... 아마
Marc.2377

typedef요청해도 C와 C ++의 차이점은 무엇입니까 ?
McSinyx

196

하여 템플릿 내에서 사용될 때 구문 이점을 갖는다. 유형 추상화가 필요하지만 나중에 템플릿 매개 변수를 지정할 수 있도록 유지해야합니다. 이런 식으로 작성해야합니다.

template <typename T> struct whatever {};

template <typename T> struct rebind
{
  typedef whatever<T> type; // to make it possible to substitue the whatever in future.
};

rebind<int>::type variable;

template <typename U> struct bar { typename rebind<U>::type _var_member; }

그러나 구문을 사용 하면이 사용 사례가 단순화됩니다.

template <typename T> using my_type = whatever<T>;

my_type<int> variable;
template <typename U> struct baz { my_type<U> _var_member; }

35
나는 이미 질문에서 이것을 지적했다. 내 질문은 템플릿을 사용하지 않으면 typedef와 다른 점입니다. 예를 들어 'Foo foo {init_value};' 'Foo foo (init_value)'대신 모두 동일한 작업을 수행해야하지만 정확히 동일한 규칙을 준수하지는 않습니다. 그래서 using / typedef와 비슷한 숨겨진 차이점이 있는지 궁금합니다.
Klaim

24

그것들은 본질적으로 동일하지만 아주 유용한 것을 using제공 alias templates합니다. 내가 찾을 수있는 좋은 예는 다음과 같습니다.

namespace std {
 template<typename T> using add_const_t = typename add_const<T>::type;
}

std::add_const_t<T>대신에 사용할 수 있습니다typename std::add_const<T>::type


지금까지 내가 아는 한, 그것은 표준 네임 스페이스 내부에 아무것도 추가 할 수있는 정의되지 않은 동작입니다
someonewithpc

5
@someonewithpc 나는 아무것도 추가하지 않고 이미 존재합니다. 유형 이름 사용법의 예를 보여주었습니다. 확인하시기 바랍니다 en.cppreference.com/w/cpp/types/add_cv
Validus 마력을

9

나는 원래의 포스터가 큰 답을 가지고 있다는 것을 알고 있지만, 내가이 글을 쓰러 뜨리는 사람에게는 여기에 토론에 가치있는 것을 추가한다고 생각 하는 제안 , 특히 typedef키워드가 향후 더 이상 사용되지 않는 것으로 표시되거나 중복 / 오래된 것으로 제거됩니다.

키워드 typedef ...를 사용하여 템플리트 별명을 소개하는 것이 좋습니다.

template<class T>
  typedef std::vector<T, MyAllocator<T> > Vec;

이 표기법은 유형 별칭을 소개하는 것으로 이미 알려진 키워드를 사용하는 이점이 있습니다. 그러나 몇 가지 disavantages [sic]도 표시되는데, 그 중 별칭이 형식을 지정하지 않고 템플릿을 나타내는 컨텍스트에서 type-name에 대한 별칭을 소개하는 것으로 알려진 키워드를 사용하는 혼동이 있습니다. Vec은 유형의 별칭 이 아니며 typedef-name에는 사용하지 않아야합니다. 이름 Vec은 가족의 이름입니다. std::vector<•, MyAllocator<•> >여기서 글 머리 기호는 type-name의 자리 표시 자이므로“typedef”구문을 제안하지 않습니다.

template<class T>
  using Vec = std::vector<T, MyAllocator<T> >;

다음과 같이 읽거나 해석 할 수 있습니다. 이제부터 Vec<T>의 동의어로 사용할 것std::vector<T, MyAllocator<T> > 입니다. 그 독서를 통해 앨리어싱에 대한 새로운 구문은 합리적으로 논리적으로 보입니다.

나에게 이것은 typedef코드를 더 읽기 쉽고 이해 하기 쉽게 만들 수 있기 때문에 C ++ 에서 키워드에 대한 지속적인 지원을 의미 합니다.

갱신 using(허용 대답에 지적 된 바와 같이) 키워드는 비 템플릿 작업 할 때 템플릿을 위해 특별히이었고, using그리고 typedef선택은 가독성과 의도의 의사 소통의 이유로 프로그래머에 완전히까지 그래서, 기계적으로 동일하다 .


2

두 키워드는 동일하지만 몇 가지주의 사항이 있습니다. 하나는로 함수 포인터를 선언하는 using T = int (*)(int, int);것이 with보다 명확하다는 것입니다 typedef int (*T)(int, int);. 둘째, 템플릿 별칭 양식을 사용할 수 없습니다 typedef. 셋째, C typedef헤더를 공개 하려면 공개 헤더에 필요합니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.